Skip to content

数据类型及其编码对应

1. 字符串对象 (String)

这是Redis最基础的类型。key都是字符串,其他复杂类型的元素也通常是字符串。

  • 编码方式 (3种)

    1. int: 当字符串内容可以被解析为一个64位有符号整数(long)时使用。
      • 优点: 极度节省内存,可以直接进行数值运算。
    2. embstr: 当字符串长度小于等于44字节时使用。redisObjectsds头在内存中是连续分配的。
      • 优点: 创建和销毁时只需一次内存分配/释放,访问局部性好。
      • 缺点: 只读。任何修改都会导致其转化为raw编码。
    3. raw: 当字符串长度大于44字节时使用。redisObjectsds头在内存中是分开分配的。
      • 优点: 可以动态修改和追加内容。
  • 编码转换

    • int -> raw: 当值不再是整数或超出long范围时。
    • embstr -> raw: 任何修改操作都会触发此转换,无论修改后长度是否超过44字节。

2. 列表对象 (List)

有序的字符串列表,支持头尾插入。

  • 编码方式 (1种)
    • quicklist: 这是Redis 3.2之后唯一的编码方式。它是一个双向链表,每个节点都是一个ziplist
      • 优点: 结合了ziplist的内存紧凑性和双向链表的灵活性,实现了空间和性能的完美平衡。
      • 历史: 早期版本曾使用ziplistlinkedlist,现已废弃。

3. 哈希对象 (Hash)

键值对的集合,类似于Java中的HashMap

  • 编码方式 (2种)

    1. ziplist: 当哈希对象同时满足以下两个条件时使用:
      • 键值对数量小于512个
      • 所有键和值的字符串长度都小于64字节
      • 优点: 内存极其紧凑。键和值在ziplist中相邻存储。
    2. hashtable (底层为dict):不满足ziplist条件时使用。
      • 优点: 查找、插入、删除的时间复杂度为O(1),性能稳定。
  • 编码转换:从ziplisthashtable的转换是单向的,一旦不满足ziplist的条件,就会转换,且不会再转回。


4. 集合对象 (Set)

无序、唯一的字符串集合。

  • 编码方式 (2种)

    1. intset: 当集合对象同时满足以下两个条件时使用:
      • 所有元素都是整数
      • 元素数量不超过512个
      • 优点: 专门为存储整数设计,内存效率极高。
    2. hashtable (底层为dict):不满足intset条件时使用。
      • 实现方式: 元素作为dictkey存储,value则全部设为NULL
      • 优点: 提供了O(1)复杂度的成员检查。
  • 编码转换:从intsethashtable单向的


5. 有序集合对象 (ZSet)

有序、唯一的字符串集合,每个元素关联一个score(分数)用于排序。

  • 编码方式 (2种)

    1. ziplist: 当有序集合同时满足以下两个条件时使用:
      • 元素数量小于128个
      • 所有元素的字符串长度都小于64字节
      • 实现方式: ziplist中,元素和其score相邻存放,并保持有序。
      • 优点: 内存占用小。
    2. skiplist: 不满足ziplist条件时使用。
      • 实现方式: 这是一个复合结构,同时使用了skiplistdict
        • skiplist: 按照score对元素进行排序,支持高效的范围查询。
        • dict: 存储元素到score的映射,支持O(1)复杂度的成员分数查找。
      • 优点: 结合了两者的优势,既能快速查找,又能高效范围查询。
  • 编码转换:从ziplistskiplist单向的


总结表

Redis对象 编码方式及条件 底层数据结构 核心优势
String int (整数值) / embstr (<=44字节) / raw (>44字节) long / 连续内存sds / 分离内存sds 针对不同大小和类型的字符串进行内存优化
List quicklist (唯一) quicklist (双向链表 of ziplist) 空间与性能的完美平衡
Hash ziplist (元素<512, 长度<64) / hashtable (其他) ziplist / dict 小数据量时内存紧凑,大数据量时性能稳定
Set intset (全是整数, 数量<512) / hashtable (其他) intset / dict 对纯整数集合进行极致内存优化
ZSet ziplist (元素<128, 长度<64) / skiplist (其他) ziplist / skiplist + dict 结合跳表和字典,同时满足高效的范围查询和单点查询

注意:上述条件中的阈值(如512, 64, 128)均可通过Redis配置文件进行修改。