Redis - list底层数据结构

list对象编码是 压缩列表(ziplist) 或者 双向链表

1、压缩列表(主要是为了节约内存)

当创建新的列表键时,列表会优先考虑使用压缩列表,因为双向链表占用的内存比压缩列表要多,并且在有需要的时候,才从压缩列表实现转换到双向链表实现。

ziplist存储在一段连续的内存上,所以存储效率很高。但它不利于修改操作,插入和删除操作需要频繁的申请和释放内存。特别是当ziplist长度很长时,一次realloc可能会导致大批量的数据拷贝。

没有维护双向指针:prev next,而是存储上一个 entry的长度和当前entry的长度,通过长度推算下一个元素的位置。牺牲读取的性能,获得高效的存储空间,因为简短字符串的情况下存储指针比存储entry长度更费内存,这是典型的“时间换空间”。

2、双向链表

双向链表linkedlist便于在表的两端进行push和pop操作,在插入节点上复杂度很低,但是它的内存开销比较大。首先,它在每个节点上除了要保存数据之外,还要额外保存两个指针(一个指向前一个节点,一个指向后一个节点,可找到前驱和后继);其次,双向链表的各个节点是单独的内存块,地址不连续,节点多了容易产生内存碎片。

3、编码转换

当list对象可以同时满足以下两个条件时,则使用 压缩列表 编码:

1)新增字符串(单个元素)的长度不超过64个字节(默认值,配置参数list_max_ziplist_value可以修改);

2)list对象保存的元素数量不超过 512 个(默认值,配置参数list_max_ziplist_entries可以修改);

不能满足这两个条件的list对象需要使用 双向链表 编码。

注意:这两个默认参数可以修改,具体请看配置文件redis.conf。

posted @ 2022-04-18 16:09  李若盛开  阅读(252)  评论(0)    收藏  举报