MST

星途 面试题库

面试题:Redis对象系统编码转换机制及优化

在Redis运行过程中,对象的编码可能会发生转换。请阐述编码转换的触发条件、转换过程以及如何通过合理设置参数或优化业务来减少不必要的编码转换,以提升Redis性能。
26.4万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

编码转换的触发条件

  1. 字符串对象
    • 当字符串对象保存的是整数值,并且这个整数值可以用 long 类型表示时,编码会转换为 int。例如,SET num 123,如果Redis判断这个值可以用 int 编码,就会转换。
    • 当字符串对象保存的字符串长度小于等于 39 字节时,编码为 embstr。若超过 39 字节,会转换为 raw
  2. 列表对象
    • 当列表对象中所有元素都是字符串对象,并且元素个数小于等于 512 个,每个字符串长度小于等于 64 字节时,编码为 ziplist。否则,转换为 linkedlist
  3. 哈希对象
    • 当哈希对象的所有键值对的键和值都是字符串对象,并且键值对个数小于等于 512 个,所有键和值的字符串长度都小于等于 64 字节时,编码为 ziplist。否则,转换为 hashtable
  4. 集合对象
    • 当集合对象中的所有元素都是整数值,并且元素个数小于等于 512 个时,编码为 intset。否则,转换为 hashtable
  5. 有序集合对象
    • 当有序集合对象的所有元素的成员都是字符串对象,并且元素个数小于等于 128 个,所有成员的字符串长度小于等于 64 字节时,编码为 ziplist。否则,转换为 skiplist

转换过程

  1. 以字符串对象从 embstr 转换为 raw 为例
    • embstr 编码的字符串对象在内存中是连续的,包含一个 redisObject 结构和一个 sds 结构。
    • 当长度超过 39 字节需要转换为 raw 时,Redis会重新分配内存,创建一个新的 redisObject 结构和一个新的 sds 结构,然后将原来 embstr 中的数据复制到新的 raw 结构中,最后释放原来 embstr 占用的内存。
  2. 以列表对象从 ziplist 转换为 linkedlist 为例
    • ziplist 是一种紧凑的存储结构。当元素个数或元素长度超出限制需要转换为 linkedlist 时,Redis会为每个元素创建一个 listNode 结构,每个 listNode 包含前一个节点、后一个节点和元素值的指针,然后将 ziplist 中的元素依次复制到 linkedlist 的节点中,最后释放 ziplist 占用的内存。

减少不必要编码转换的方法

  1. 合理设置参数
    • 可以通过修改Redis配置文件中的相关参数来调整编码转换的阈值。例如,对于列表对象、哈希对象等,可以通过调整 list-max-ziplist-entrieslist-max-ziplist-value (列表对象相关)、hash-max-ziplist-entrieshash-max-ziplist-value (哈希对象相关)等参数,根据业务数据特点,适当增大这些阈值,减少编码转换的可能性。
  2. 优化业务
    • 数据写入:在写入数据时,尽量控制数据的规模和大小。例如,对于列表,尽量避免一次性插入大量元素或者过长的字符串元素;对于哈希,避免键值对过多或键值过长。
    • 数据结构选择:根据业务场景选择合适的数据结构。如果知道某个集合主要是存储整数值且数量不会太多,就使用集合对象而不是哈希对象来存储,这样可以保持 intset 编码,提升性能。同时,在设计数据结构时,尽量保持数据类型和规模的一致性,减少因数据变化导致的编码转换。