暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis String 数据结构

461

Redis运行于独立的进程,将数据保存在内存中,并提供多种手段持久化内存数据。

数据结构

Redis没有传统数据库的table模型。schema所对应的db仅以编号区分。实际使用中,通常以“:”作为分隔符,将命名空间值和业务key相连接

Redis常用的value包含5种数据类型:string、list、set、map、sorted-sort

value通用数据结构

  1. typedef struct redisObject{

  2.    unsigned type:4;

  3.    unsigned encoding:4;

  4.    unsigned lru:REDIS_LRU_BITS;

  5.    int refcount;

  6.    void *ptr;

  7. } robj;

复制
  • type: 指的是string、list等结构化数据类型

  • encoding: 指的是结构化类型具体的实现方式,同一个类型可以有多种实现,例如String可以用int来承载,可以用封装的char[]来承载,List可以用ziplist或者链表来承载

  • lru: 本对象的空转时长,用于有限内存下长久不访问的对象的清理

  • refcount: 应用计数用于对象的垃圾回收

  • ptr: 以encoding方式实现这个对象的实际承载者的地址。

String

String可以表达3种值的类型:

  • 字节串

  • 整数

  • 浮点数

三种类型根据具体场景由Redis完成相互间自动转型,整数和浮点数类型的value具备自增、自减等数字型操作

针对String类型的value还具备简单的CAS操作,根据给定的key是否存在设置值

基本操作

操作描述使用方法
INCR将指定的key的内容加1INCR
DECR将指定的key的内容减1DECR
INCRBY将指定key的内容增加给定的值INCRBY
DECRBY将指定key的内容减去给定的值DECRBY
INCRBYFLOAT将指定key的内容增加给定的浮点数值INCRBYFLOAT
APPEND将指定字节串的内容添加到指定key对应的value后APPEND
GETRANGE对字节串value做范围截取GETRANGE
SETRANGE将指定字符串内容覆盖,指定key对应的value,从指定位置开始覆盖SETRANGE
STRLEN获取字节串的长度STRLEN
GETBIT对字节串value,获取指定偏移量上的bitGETBIT
SETBIT将字节串value视为bit串并设置从给定起始位置起设置值SETBIT
BITCOUNT将字节串value视为bit并统计1的数量BITCOUNT
BITOP对多个key的value值做位操作,如:XOR、OR、AND、NOTBITOP

针对String类型的value还具备简单的CAS操作,根据给定的key是否存在设置值

内存数据结构

String类型value内部以int、SDS(simple dynamic string)作为结构存储。int用来存放整形数据,sds存放字节/字符串和浮点型数据

sds结构

  1. typedef struct sdshdr{

  2.    unsigned int len;

  3.    unsigned int free;

  4.    char buf[];

  5. };

复制

buf[]数组:存储了字节串的内容,但是它本身的长度通常大于所存储的内容的长度,所存储的内容的长度可以通过len字段直接在O(1)的复杂度内得出

Redis采用类似C的做法存储字符串,即以'\0'结尾,但是这并不表示业务数据内容不能包含'\0'。

上图示例中,len的值为5,free的值为2。

buf中free区域的引入提升了sds对于字节串处理的能力,减少了处理过程中可能遇到的内存申请和释放的次数。如果APPEND操作的字节串的长度大于free的值,则需要扩容,如果小于free的值,不用进行扩容,不用重新申请内存。

对字节串长度进行缩减操作时,buf中的free部分不会立即释放而是继续保留以便后续操作利用

buf的扩容和缩容

当业务操作超出了buf的现有容量时,sds会对buf进行扩容,触发条件如下:

  • 字节串初始化时,buf的大小=len+1,即加上作为界定符的'\0'刚好等于业务数据的长度。

  • 当对串的操作完成后预期的串长度小于1MB时,扩容后的buf大小=业务串预期长度*2+1,即不考虑最后的'\0',buf倍增

  • 对于大于1MB的长串,buf总是留出1MB的free空间,即buf以业务串的2倍来扩容,单最大留出1MB的空间。

字节串和字符串

sds中存储的内容可以是ASCII字符串,也可以是字节串。由于sds通过len字段确定业务串的长度,业务串可以存储非文本内容

sds编码优化

value部分通常由两部分构成:redisObject和redisObject的ptr指向的sds部分。在创建value对象时,通常需要为redisObject和sds申请两次内存。对于很多短小的字节串,sds长度较小,可以把redisObject和sds连续存放,在创建redisObject时,一次性将sds对象的内存也申请了,初始化redisObject时同时设置sds的内容


文章转载自程序员修炼笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论