面试题解-Redis的String是如何实现的?

第44题: Redis 的String 是怎么实现的?为什么不直接用c的字符串?

Redis 没有直接使用C 语言的字符串表示,而是自己构建一种简单动态字符串(SDS: simple dynamic string)。

Redis 中的String 都是SDS,例如我们执行这样一条命令:

redis> SET blog angela

那么Redis 在内存中创建了一个键值对,

  • 键:键是一个字符串对象,对应底层实现是一个保存字符串“blog” 的SDS;
  • 值:值也是一个字符串对象,对应底层实现是一个保存字符串是“angela”的SDS。

如果执行

redis> RPUSH blog "angela" "de" "blog"

那么Redis 将在内存中创建一个键值对,键还是一个SDS,存放“blog”,值是一个列表,存放三个SDS,“angela”、“de”、“blog”

SDS如何实现的呢?

首先SDS被定义为这样一个结构体:

struct sdshdr {
   char buf[];//字节数组,用于保存字符串
   int len;//记录buf数组中已使用字节的数量
   int free;//记录buf数组中未使用字节的数量
}

举个例子:

现有执行redis> SET blog angela 命令后,value值在redis 中存放如下图所示,buf存放字节数组(真实数据),len表示存放字符串的长度(不包括结束符号’’),free表示剩余空间,可以看到还剩5个字节。

面试题解-Redis的String是如何实现的?

SDS遵循了C语言字符串以空字符结尾的惯例,保存空字符的1个字节空间不在SDS 的len属性里面。这样做有个好处是我们直接可以复用C 提供的库函数,比如打印字符串,直接用C 提供的printf("%s", s->buf);

那又是为什么不直接用C语言提供的字符串呢?

在C语言中,表示一个“angela” 的字符串如下图所示,结束也是通过空字符表示:

面试题解-Redis的String是如何实现的?

C语言的字符串和SDS的区别如下:

  • 长度获取效率:C语言如果需要获取字符串长度,需要从头开始遍历,时间复杂度O(n),SDS提供len属性,访问时间复杂度O(1), Redis的strlen 获取字符串长度函数性能毫无压力;

  • 杜绝溢出:C字符串不记录自身长度的另一个问题是容易造成缓冲区溢出,比如要做字符串拼接,char *strcat(char *dest, const char *src), 讲src 字符串拼到desc字符串,如果desc忘记提前扩容,就会溢出,而恰好desc后面正好有数据,则会被覆盖;

  • 减少内存重分配:对于Redis这种内存数据库,很多场景会频繁更新value的值,那如果采用C字符串,value长度有变化,就需要频繁分配内存,SDS做了内存的预分配和惰性释放,能有效减少内存分配次数,内存的重分配代价还是很高昂的,对于Redis这种对性能要求非常高的缓存产品,这种性能损耗是不能接受的;

  • 二进制安全:C字符串必须符合某种编码(比如ASCII),除了空字符结尾,字符串中间是不能包含空字符的,否则会被误以为是字符串结尾。这就限定了C字符串不能用来存储类型图片、音频、视频、压缩文件这种二进制书数据,但是SDS可以,SDS设计的API都是二进制安全的。

对Redis感兴趣的可以加我微信guofu-angela, 把你拉到Redis群,一起探讨缓存的问题。

今天文章有点短,最近发现有个蛋疼的事情,有好几个读者私我,让我帮忙看面试进度,他大爷的,内推的想不起来找我,快拿到offer了找我看进度。

面试题解-Redis的String是如何实现的?

开个玩笑,希望玩家们都能拿到心仪的offer,你们可以在公众号后台许愿。

所以还是要强调内推记得找我,我会认真写面试推荐。

另外在招22届毕业实习生,有22届毕业的同学帮忙推荐给我,把我这篇文章或者微信(guofu-angela)发给他/她。

大家如果不想漏看,可以星标一下公众号。


原文始发于微信公众号(安琪拉的博客):面试题解-Redis的String是如何实现的?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/25241.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!