redis底层数据结构之压缩列表

1. 问题

压缩列表在Redis中用来存储哪些类型的数据?

2. 介绍

压缩列表是redis为了节省内存而开发的,由一系列特殊编码的连续内存块组成的有序数据结构。

用途: zset键,哈希键

3. 底层实现

image

说明:

ziplist_bytes: 四个字节,记录占用总字节数

ziplist_tail_offset: 四个字节,代表第一个节点距离最后一个节点的字节数

 ziplist_length: 两个字节,代表entry节点个数

zlentry: 压缩列表实体

oxFF: 一个字节,代表固定结束符

zlentry数据结构

 

说明: previous_entry_length代表前一个节点的总字节数

encoding代表压缩列表存储数据的格式,可以存储16位,32位,64位的整数以及字符串

content代表具体的内容

4. 注意点

当哈希对象可以同时满足以下两个条件时, 哈希对象使用 ziplist 编码:

  1. 哈希对象保存的所有键值对的键和值的字符串长度都小于 64 字节;
  2. 哈希对象保存的键值对数量小于 512 个;
  3. 不满足上述条件,会使用hashtable

连锁更新: 

假设原本 entry1 节点占用字节数为 211(小于 254),那么 entry2 的 previous_entry_length 会使用一个字节存储 entry1的字节数211,现在我们新插入一个节点 NEWEntry,这个节点比较大,占用了 512 个字节。

那么,我们知道,NEWEntry 节点插入后,entry2 的 previous_entry_length 存储不了 512,那么 redis 就会重分配内存,增加 entry2 的内存分配,并分配给 previous_entry_length 五个字节存储 NEWEntry 节点长度。

看似没什么问题,但是如果极端情况下,entry2 扩容四个字节后,导致自身占用字节数超过 254,就会又触发后一个节点的内存占用空间扩大,非常极端情况下,会导致所有的节点都扩容,这就是连锁更新,一次更新导致大量甚至全部节点都更新内存的分配。

5. 测试

发布了210 篇原创文章 · 获赞 105 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/u010627840/article/details/103766937
今日推荐