Redis数据结构和内部编码

警告
本文最后更新于 2023-03-04,文中内容可能已过时。

字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过 512MB

https://image.linux88.com/2023/03/04/9f2b435685f3de46d423e214d957102b.svg

它通常用于缓存,共享Session,分布式锁,计数器,限速,全局ID等。

如果存储的是结构化数据,还可以考虑 HashRedisJSON

8个字节的长整型。

小于等于45个字节的字符串。

大于45个字节的字符串。

1
2
3
4
127.0.0.1:6379> set key "aaaaaaaaaabbbbbbbbbbcccccccccceeeeeeeeeefffff"
OK
127.0.0.1:6379> OBJECT encoding key
"raw"

每个哈希最多可以存储 $2^{32} - 1$(4,294,967,295)个key-value对。实际上,Hash 仅受限制于总内存的限制。它通常用于购物车,用户信息等。

https://image.linux88.com/2023/03/04/f78a7fa93780a41065699fd32a455a90.svg

当field个数比较少且没有大的value时,内部编码为ziplist。

使用 hashtable 会比 ziplist 消耗更多内存

当有 hash-max-ziplist-value value大于64字节或当 hash-max-ziplist-entries field 个数超过512内部编码会由 ziplist 变为 hashtable

List 是 Redis string 链表的实现。最大长度为 $2^{32} - 1$ (4,294,967,295) 个元素。经常用于栈和队列,文章列表,消息队列(大型项目不建议有内存限制)。

https://www.redis.com/wp-content/images/academy/redis-in-action/RIA_fig1-02.svg

  • lpush+lpop=Stack(栈)
  • lpush+rpop=Queue(队列)
  • lpsh+ltrim=Capped Collection(有限集合)
  • lpush+brpop=Message Queue(消息队列)
1
list-max-ziplist-size -2
  • 配置为正:表示限制队列的长度
  • 配置为负数:表示限制大小
    • -5:最大 64 kb <— 正常环境不推荐
    • -4:最大 32 kb <— 不推荐
    • -3:最大 16 kb <— 可能不推荐
    • -2:最大 8 kb <— 不错
    • -1:最大 4kb <— 不错

当列表类型无法满足 ziplist 的条件时,Redis会使用 linkedlist 作为列表的内部实现。

Redis Set 是唯一成员的无序集合。最多可以有 $2^{32} - 1$ (4,294,967,295) 成员。

它通常用于社交关系表现,集合运算。

https://image.linux88.com/2023/03/04/559dcba38576f82e20a96af317d1138c.svg

当集合中的元素都是整数且元素个数小于set-max-intset-entries 配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。

当集合类型无法满足 intset 的条件时,Redis会使 用 hashtable 作为集合的内部实现。

Redis sorted set 是按分数(score)排序的唯一字符串的集合。

它通常用于排行榜,构建滑动窗口速率限制器。

https://image.linux88.com/2023/03/04/8eb2a8101ac0428d7ba6c5494ffeee1a.svg

当有序集合的元素个数小于 zset-max-ziplist-entries 配置(默认128个)

每个元素的值都小于 zset-max-ziplist-value 配置(默认64字节)时,

Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。

ziplist 条件不满足时,有序集合会使用 skiplist 作 为内部实现,因为此时ziplist 的读写效率会下降。

Redis Stream 是一种数据结构,其作用类似于 append-only log 。您可以使用流实时记录和同时联合事件。 Redis 流用例示例包括:

  • 事件溯源(例如,跟踪用户操作、点击等)
  • 传感器监控(例如,现场设备的读数)
  • 通知(例如,将每个用户的通知记录存储在单独的流中)

Redis 为每个流条目生成一个唯一的 ID。您可以使用这些 ID 稍后检索它们的关联条目,或者读取和处理流中的所有后续条目。

Redis 流支持多种修剪策略(以防止流无限制地增长)和多种消费策略(XREADXREADGROUPXRANGE )。

Redis 地理空间索引让您可以存储坐标并进行搜索。此数据结构可用于查找给定半径或边界框内的附近点。

HyperLogLog 是一种估计集合基数的数据结构。作为一种概率数据结构,HyperLogLog 以完美的准确性换取高效的空间利用。

Redis HyperLogLog 实现最多使用 12 KB,并提供 0.81% 的标准错误。

HyperLogLog 可以估计最多包含 18,446,744,073,709,551,616 ($2^{64}$) 个成员的集合的基数。

Redis 位图是字符串数据类型的扩展,可让您将字符串视为位向量。您还可以对一个或多个字符串执行按位运算。常用于统计用户登录天数和每天活跃用户。


Redis configuration file example

Redis data types

Redis in Action

相关内容