愚公系列2022年05月 .NET架构班 046-分布式中间件 Redis存储原理之string

网友投稿 609 2022-05-29

前言

1.SDS概念

Redis中字符串的实现,Simple Dynamic String简单动态字符串,是一数据结构。

Redis是用C语言实现的,但C语言本身没有字符串类型(只能用字符数组 char[]实现)。所以就会有以下问题:

【愚公系列】2022年05月 .NET架构班 046-分布式中间件 Redis存储原理之string

使用字符数组必须先给目标变量分配足够的空间,否则可能会溢出。

如果要获取字符长度,必须遍历字符数组,时间复杂度是 O(n)。

C 字符串长度的变更会对字符数组做内存重分配。

通过从字符串开始到结尾碰到的第一个’\0’来标记字符串的结束,因此不能保 存图片、音频、视频、压缩文件等二进制(bytes)保存的内容,二进制不安全。

而SDS的特点:

不用担心内存溢出问题,如果需要会对SDS进行扩容。

获取字符串长度时间复杂度为 O(1),因为定义了len属性。

通过“空间预分配”( sdsMakeRoomFor)和“惰性空间释放”,防止多次重分配内存。

判断是否结束的标志是 len 属性(它同样以’\0’结尾是因为这样就可以使用 C语言中函数库操作字符串的函数了),可以包含’\0’。

一、Redis存储原理之string

1. string结构

redisObject 结构如下:

typedef struct redisObject { unsigned type:4; /* 对象的类型,包括:OBJ_STRING、OBJ_LIST、OBJ_HASH、OBJ_SET、OBJ_ZSET */ unsigned encoding:4; /* 具体的数据结构 */ unsigned lru:LRU_BITS; /* 24 位,对象最后一次被命令程序访问的时间,与内存回收有关 */ int refcount; /* 引用计数。当 refcount 为 0 的时候,表示该对象已经不被任何对象引用,则可以进行垃圾回收了 */ void *ptr; /* 指向对象实际的数据结构 */ } robj;

SDS结构如下:

/* sds.h */ struct __attribute__ ((__packed__)) sdshdr8 { uint8_t len; /* 当前字符数组的长度 */ uint8_t alloc; /*当前字符数组总共分配的内存大小 */ unsigned char flags; /* 当前字符数组的属性、用来标识到底是 sdshdr8 还是 sdshdr16 等 */ char buf[]; /* 字符串真正的值 */ };

2.string编码类型

字符串的编码有三种:

int:存储 8 个字节的长整型(long,2^63-1)。大小超过了 long 的范围 (2^63-1=9223372036854775807)时会自动转成embstr。

embstr:代表 embstr 格式的 SDS(Simple Dynamic String 简单动态字符串), 存储小于 44 个字节的字符串。分配一次内存空间,而且是只读的。

raw:存储大于 44 个字节的字符串(3.2 版本之前是 39 字节)。分配二次内存空间。

3.应用场景

Redis 分布式

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Vue(十)vuex
下一篇:从 Leader 的角度理解 DevOps
相关文章