Redis的Encoding编码分类

Redis的encoding编码

Redis的底层设计中RedisObject存在encoding用于针对数据进行优化,而在不同的类型中也有不同的优化选择,这篇文章只对所有的编码类型进行描述,并不说明Redis数据类型分类选择优化编码规则进行描述

#define OBJ_ENCODING_RAW 0     /* Raw representation */
#define OBJ_ENCODING_INT 1     /* Encoded as integer */
#define OBJ_ENCODING_HT 2      /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */

raw

即普通的SDS普通编码方式的编码类型,该编码类型为原始类型,可通用存储数据

int

数据会先设置为原始类型,然后判断长度是否大于20个字节(指针本身就占用了8个字节,尝试不进行创建内存,而直接使用指针地址)再进行尝试转换为整型值(20位大小的整型值就在8个字节以内),就可以使用指针来存储整型值,节省了内存空间与内存IO

ht(hashTable)

该类型在实际上的表现就是dict(字典),这是因为该结构主要服务为Redis的hash数据类型,而该类型实质是就上就类似一个嵌套的MAP

该编码在hash,set中使用,Set 数据结构底层实现为一个value 为 null 的 字典( dict )

zipmap

在这里插入图片描述
可以看成压缩字典,根据ziplist类似原理来实现

linkedlist

常见的双端链表结构,数据存储在节点上,是老的list类型的实现,被quicklist替换
淘汰猜测:数据存储在上造成需要持续IO+链表内存地址分散

ziplist

在这里插入图片描述
在这里插入图片描述
采用紧凑的二进制机构存储

  • zibytes 当前存储多少数据

  • zltail 尾节点位置(索引)

  • zllen ziplist存在多少个元素

  • zled:255 标识数据结尾

  • entry

    • prerawlen 诺前数据项小于254,则占用1 byte 否则占用标记位+4 byte 即5byte 表示前一个数据的长度
    • len 用于表示数据的长度等等
    • data 实际存储数据
可用设置
  • hash-max-ziplist-entries 512 // 在hash类型ziplist 元素个数超过 512 ,将改为hashtable编码
  • hash-max-ziplist-value 64 // 在hash类型单个元素大小超过 64 byte时,将改为hashtable编码

该编码在hash,list中使用

intset

在这里插入图片描述

用于存储可以用整型表示的数据,使用该数据编码时,数据有序且唯一,查询数据采用二分查找O(log n) 时间复杂度查询,据存储会根据数据的最大值进行限制和升级,但是只能存储int类型数据

可用设置
  • set-max-intset-entries 512 //set类型 intset 能存储的最大元素个数,超过则用hashtable编码

skiplist(跳表)

在这里插入图片描述

  • header 头节点 记录层级 即索引层
  • tail 位节点 用于从后往前遍历
  • length 数据数量
  • level 跳表层高 开始遍历层
  • forward 数据层级 越多就表示代表的层级越多,直接存在节点上,而该层级的数量是根据随机函数进行生产的(越高的层级生成可能越低,越低的层级生成可能越高),如果生成的层级大于最大层级就会更新最大层级
  • 数据是直接存储在节点上的
可用设置
  • zset-max-ziplist-entries 128 // zset类型元素个数超过128 ,将用skiplist编码

  • zset-max-ziplist-value 64 // zset类型单个元素大小超过 64 byte, 将用 skiplist编码

embstr

用于针对CPU缓存行优化,每次拿取64byte,而每次获取redisObject只有16byte,sds占用4byte 为了利用剩余空间,在value长度未大于44byte时采用该类型,该类型固定大小长度为64byte

quicklist(双端链表)

在这里插入图片描述
当数据存储到一定长度时,为避免数据退化,会进行分裂为多个节点,将在ziplist上添加上层结构
通过设置每个ziplist的最大容量,quicklist的范围数据压缩,提升数据存储效率

  • 单个ziplist节点最大能存储8 kb ,超过则进行分裂,将数据存储在新的ziplist节点中,redis.conf中存在说明

     list-max-ziplist-size -2
    
  • 节点压缩

    list-compress-depth 1
    

    0表示所有节点,都不进行压缩,1表示从头节点走一个,尾节点往前走一个不用压缩,其他的全部压缩,2,3,4…以此类推,中间数据并不频繁访问

该结构在list类型中使用

stream

Redis Stream 是 Redis 5.0 版本新增加的数据结构,该编码是支持stream的
在这里插入图片描述
stream详细

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿嘿嘿1212

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值