MST

星途 面试题库

面试题:Redis中常见的对象编码有哪些,在什么条件下会触发编码转换?

请阐述Redis常见对象编码如int、embstr、raw等,并详细说明在哪些场景下会从一种编码转换为另一种编码,例如在数据量、数据类型等方面发生何种变化时会触发编码转换。
25.4万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

Redis常见对象编码

  1. int
    • 编码描述:当一个键值对中的值是一个整数值,并且这个整数值可以用64位有符号整数(long类型)表示时,Redis会使用int编码来存储这个值。这种编码方式非常紧凑和高效,因为它直接使用一个64位的整数来存储数据,而不需要额外的空间来存储对象头信息等。
    • 适用场景:适合存储范围在[-9223372036854775808, 9223372036854775807]之间的整数。例如存储用户ID、计数器等简单整数数据。
  2. embstr
    • 编码描述:embstr编码用于存储短字符串。它是一种优化的编码方式,将对象头和字符串内容连续存储在一块内存中。Redis的对象头通常为16字节左右,当字符串长度较短时(小于等于44字节,不同版本可能略有差异),使用embstr编码可以减少内存碎片,提高内存利用率。
    • 适用场景:适用于存储长度较短的字符串,比如常见的配置项名称、简短的标识字符串等。例如"name","status"等字符串。
  3. raw
    • 编码描述:当字符串长度超过embstr编码能够处理的最大长度时,Redis会使用raw编码。raw编码会为对象头和字符串内容分别分配内存,这种方式在处理长字符串时更为灵活,但也会产生更多的内存碎片。
    • 适用场景:适用于存储较长的字符串,如文章内容、较长的JSON字符串等。

编码转换场景

  1. int到raw
    • 数据类型变化:如果原来存储的是整数,后续对这个键执行操作,使得值不再是整数类型(例如通过SET key "new string value"将整数值变为字符串值),那么编码会从int转换为raw。
    • 数据量变化:理论上单纯的整数数据量变化(在64位有符号整数范围内)不会触发int到raw的转换。但如果通过某些操作改变了数据类型,如使用APPEND命令在整数值后追加字符串,会导致编码转换为raw。
  2. embstr到raw
    • 数据量变化:当使用APPEND命令向embstr编码的字符串追加内容,导致字符串长度超过了embstr编码所能处理的最大长度(通常小于等于44字节),Redis会将其编码从embstr转换为raw。这是因为embstr编码要求对象头和字符串内容在一块连续内存中,长度超出限制后无法满足此条件,只能采用raw编码分别分配内存。
  3. 其他情况
    • 对于哈希对象,如果哈希对象中元素个数较少且每个元素的键和值长度较短,会使用ziplist编码。但当元素个数超过hash-max-ziplist-entries(默认512)或者任何一个键值对长度超过hash-max-ziplist-value(默认64字节)时,哈希对象会从ziplist编码转换为hashtable编码。类似的,对于列表对象,当列表元素个数较少且每个元素长度较短时使用ziplist编码,元素个数超过list-max-ziplist-entries(默认512)或者元素长度超过list-max-ziplist-value(默认64字节)时,会转换为linkedlist编码(Redis 3.2之后,linkedlist被quicklist替代)。这些编码转换也间接影响了对象内部字符串等元素的编码,例如元素中的字符串如果长度变化可能会在embstr和raw编码间转换。