前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis源码学习之字符串对象

Redis源码学习之字符串对象

原创
作者头像
里奥搬砖
修改2018-11-14 16:06:35
1.1K0
修改2018-11-14 16:06:35
举报

前文中提到,Redis的字符串对象的底层数据结构有三种,分别是整数编码、EMBSTR编码和SDS编码。在不同使用场景下进行相互切换,起到节约内存的作用。

1.整数编码

针对将某个key对应的值设置为整数类型的情况,有以下两种情况

  1. Redis服务器没有配置LRU相关的淘汰策略&&设置的整数值在共享整数对象范围内,则使用整数共享对象。
  2. 如果不能使用整数共享对象,则将原对象编码为整数编码类型,并释放原对象使用sds空间。

举个例子,我们使用如下命令:

代码语言:javascript
复制
set a 11111

将键a的值设置为11111(设置为11111是因为共享对象的范围是[0,10000]),我们通过GDB设置断点,打印相关变量:

从图中可以看到,字符串对象的encoding字段从RAW变成了INT,对应的底层数据结构指针也发生了相应的变化。使用【object encoding】命令查看编码类型。

2.EMBSTR编码

EMBSTR编码是专门用于存储短字符串而实现的,当字符串的长度不大于39个字节的时候,就会将该字符串对象编码为EMBSTR类型。EMBSTR编码使用一块连续的内存空间,可以更好的利用到cache line。此外,对比RAW编码,在内存分配和内存释放的次数上都降低了一倍。

其中,创建EMBSTR编码的字符串代码如下:

代码中可以看到,实际上EMBSTR的底层数据结构也是复用了sdshdr结构体,但是在创建的时候只调用了一次zmalloc,而RAW编码则会调用两次,因此,EMBSTR是将redisObject和sdshdr存放到一块连续的内存空间中去了。值得一提的是,Redis并没有为EMBSTR实现修改的方法,所以任何对EMBSTR编码的字符串的修改(例如append),都会使其从EMBSTR转为RAW编码,再进行修改操作。

Redis在处理客户端请求命令时,会针对命令字符串的长度选择使用EMBSTR还是RAW,在后面说到“服务器与客户端交互”时还会具体介绍,代码如下(networking.c:processMultibulkBuffer):

3.SDS编码

SDS编码类型的字符串是Redis基于自身实现的简单动态字符串,它的结构如下图所示:

从图中可以看出,SDS通过len字段记录字符串实际长度,通过free字段记录字符串剩余长度,此外由于Redis是C语言编写,所以继承了C语言字符串以“\0”作为终止符的规则,额外分配一个字节空间给\0(为了兼容C字符串API),因此图中这个字符串(hello)总共占用的内存空间为5+5+1=11个字节。那么,为什么Redis要设计SDS而不直接使用C语言的字符串呢?主要有以下几点:

  1. 避免C字符串的缓冲溢出问题,SDS提供的各种API会根据SDS字符串的剩余空间做扩容策略,而C字符串是不会检查的
  2. 通过len字段可以很方便的获取SDS字符串长度,而C字符串需要遍历查找\0字符
  3. 减少字符串内存空间分配次数,由于free字段的存在,可以在创建字符串的时候预先分配一定的free空间,这样针对一些append操作就不需要再分配一次了。当SDS字符串长度在1M字节以下时,分配的free长度和len长度是一样的;当大于1M字节时,至多分配free长度为1M字节,所以这里也提醒我们当在Redis中存放一个长度M级别的字符串时,对它的修改操作会有额外的内存开销。
  4. 二进制安全,因为长度len字段的存在,SDS字符串API都是二进制安全的。

4.思维导图

欢迎关注我的公众号
欢迎关注我的公众号

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档