前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从本地到云端:看 Redis 如何降本增效

从本地到云端:看 Redis 如何降本增效

原创
作者头像
花花Binki
发布2024-08-21 23:49:55
270
发布2024-08-21 23:49:55
举报
文章被收录于专栏:岚的工作随笔
封面
封面

前言

假设不存在数据库,数据都存在一个文本文件里,想搜索"腾讯云开发者社区",要怎么去搜索?

在Linux中,有grep、awk等命令来查找;使用一些高级语言,像Java,Python也可以通过IO流来读取一个文件。到这为止,有什么可以优化的点吗?

从外存,内存到缓存

在计算机当中,数据是存在磁盘的。当在Windows平台上进行解压缩文件操作时,打开任务管理器可看到清晰的数据读写,通常是MB/s的级别。

文件解压时产生的读写(固态)
文件解压时产生的读写(固态)

而内存呢?切到内存上,只能看见3200MT/s。换算后,内存与外存在带宽上就能相差几百倍。寻址能力更是相差几万倍。可见二者差距。

DDR4:常见的工作频率为2133MHz,单通道带宽可达25.6GB/s(2133MHz * 64bit/8)。 MT/s /2 = MHz;

回到开头的话题,抛出第一个疑问点:假如文件足够大时,硬盘(读写)率先成为瓶颈,代码该怎样去解决呢?先来看数据库的优化的做法。

数据库中的存储优化

data page
data page

现在有一张表,很多行数据,存在物理磁盘中。数据库中用了很多4k的小块,这里的4k和磁盘的对齐方式正好匹配,一次I/O对应一块区域。结合上图,可以想到数据库的建表中的索引,再加上数据库的独特的B+树结构,减少很多磁盘的寻址,IO的流量。同时,索引也是小块page。

索引就如查字典一样,无论多么复杂的字,都可以几步内检索到。

对齐方式验证:新建一个空白文档,输入一堆数字保存后 文件大小:1.14KB(不到4KB),占用空间:4KB。

缓存

B+树和data page就是万能方案了吗?并不是。假设有10个人,100个,1000个人来查字典,一本字典有点显得捉襟见肘。实际上,有很多人查的字是重复的,我们就可以让前来查字典的人先去问查过字典的人,这样就形成了缓存。

缓存在一定程度上弥补了硬盘的缺陷,当然也带来了更多的管理问题。就缓存用的数据库来说,Redis已经成为首选。

Redis

先来看看他有多火吧!

db-engine ranking
db-engine ranking

键值对型(key-value)的第一,总数据库的第六。

为什么是 Redis

在与前端进行交互时,较为常用的是JSON格式。那试着用这种方式与缓存交互?

存入数字,字符串,列表都不在话下,但取出来就犯愁了。一个大列表只取一条数据,I/O很快成为瓶颈。那么这种类似JSON一样传输文件的就是Memcache。

全部数据返回优点不太现实,于是尝试在“值”加入类型,再给于一定增删改查方法,这种数据向计算移动的做法。恭喜,到此已经入门了Redis的存储方式。

Redis 的字符串

先来看一段代码

代码语言:shell
复制
set key1 9 # 存一个key为key1,值为9的对象
object encoding key1 # 查看类型,结果是int

append key1 'a'  # key1末尾追加字符串'a',
get key1 # 9a
object encoding key1 # raw

这就是Redis的字符串,get、set都是String类型的内置方法。但他又与传统的类型不同,从2和6行,变化了的编码方式可以看出来,这是一种动态类型的字符串,Redis用SDS来存储。

SDS(Simple Dynamic String)简单动态字符串。

重写字符串有什么好处呢?

①解决遗留问题

取得字符串长度是一个很常见的操作,C语言的实现方式是遍历(Redis由C开发),Redis直接用一个length来维护。

代码语言:c
复制
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used:已经使用长度 */
    uint8_t alloc; /* excluding the header and null terminator:简单理解为总长度 */
    unsigned char flags; /* 3 lsb of type, 5 unused bits :SDS编码类型,当前类型为sdshdr8*/
    char buf[]; /* 实际存储内容 */
};

②优化内存

从上述代码中还可以看到__attribute__ ((__packed__))这样一段,其实是为了告诉编译器,不使用字节对其,而使用紧凑型分配内存。

③二进制安全

在IO中读写文件,分为两种,字符型和字节型。字符型代表就是txt文本。字节流就很多了,图片,java编译后的class文件。字节流可以通过一定编码格式变成字符,而反过来就很难操作。Redis正是采用字节流。

使用上有什么亮点呢?

比如去存储一个中国的“中”字,UTF-8编码会占三个字节,GBK编码就会占两个字节。假如你在链接时使用了--raw,这样就解锁了ASCII编码,取出来的值又变成了其他方式。

团队在使用时要统一编码格式。 还有很多优化的点,篇幅有限,先略过。

云上的 Redis

笔者作为开发人员,只熟悉一些简单部署命令,很多时候需要一个面板来操作。加上Redis是内存数据库,加在后台服务的机器上,很影响性能,所以很有必要去云上选购一台Redis。

  • 内网低延迟 无论是数据库或是其他服务,通过外网连接,网速都将会成为性能瓶颈。云厂商早就想到了这一点,所以勾选的时候注意服务器省市和分区。购买调节参数时,换配置会重置分区以及其他选项需注意。
  • 全面的控制面板 自动备份,主备替换,一件导入配置等独特的功能满足基本所需。
  • 数据看板 有种看到图表就掌控大全的舒适感。
腾讯云数据库 Redis 功能一览
腾讯云数据库 Redis 功能一览

案例:热门排行榜

给几个热门话题做一个排行榜,需要准备什么?

  • 话题唯一
  • 热度数值
  • 实时排行
  • 高频次的IO

Redis中恰好有这样一个数据类型,完美契合,那就是Sorted Set。

数据结构

大多数语言都有set结构,它是一种不重复元素的集合,而Redis的Sorted Set在唯一性的基础上,又增加了有序性。

底层结构

  • listpack(7.0版本之前是ziplist)
  • skiplist + dict

这个顺序也代表着,前者适合较小范围的场景。

代码语言:c
复制
/* ZSETs use a specialized version of Skiplists: zsets使用一种特殊版本的skiplists */
typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;
  • ele 真实数据,可以用来存储话题
  • score 分数,可以存放热度值或其加权计算后的数值

具体操作

Java 中可以使用三种方式连接Redis

  • Jedis
  • Lettuce
  • Redisson
  • Spring Data Redis(基于Redis)

由于API不同,所以下面主要来说具体Redis的命令。

向“热搜”榜单添加话题与分数

代码语言:shell
复制
ZADD '热搜' 1 "黑神话:悟空"
ZADD '热搜' 2 "腾讯云"
ZADD '热搜' 3 "云游戏"

获取热搜榜

代码语言:shell
复制
ZREVRANGE '热搜' 0 9 WITHSCORES

返回结果

代码语言:txt
复制
 1)  "云游戏"
 2)  "3"
 3)  "腾讯云"
 4)  "2"
 5)  "黑神话:悟空"
 6)  "1"

更新热搜榜

代码语言:shell
复制
ZINCRBY '热搜' 999 "黑神话:悟空"

再去获取排行榜,已经变成了

代码语言:txt
复制
 1)  "黑神话:悟空"
 2)  "1000"
 3)  "云游戏"
 4)  "3"
 5)  "腾讯云"
 6)  "2"

到现在为止,已经获得了一个简单的热搜榜。

one more thing

Redis的功能不止于此,这些都来自于他独特的数据类型以及架构。不过,最常用的还是缓存功能。经过常见八股文的洗脸,就可以成为一个高手!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 从外存,内存到缓存
    • 数据库中的存储优化
      • 缓存
      • Redis
        • 为什么是 Redis
          • Redis 的字符串
            • 重写字符串有什么好处呢?
        • 云上的 Redis
        • 案例:热门排行榜
          • 数据结构
            • 具体操作
            • one more thing
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档