美文网首页
Redis - list底层数据结构实现

Redis - list底层数据结构实现

作者: kyo1992 | 来源:发表于2021-04-07 08:12 被阅读0次

前言

List是一个按加入时序排序的数据结构,Redis采用quicklist(双端链表) + ziplist 作为List的底层实现

使用双端链表的缺点

Redis并没有直接采用双端链表存储数据,因为每两个节点需要两个指针连接,在64位系统下,每个指针所占内存为8byte,如果链表存储大量小数据,那么指针的开销就会很浪费。

ziplist

是一个连续的内存空间,分为head,data,end三部分,一个ziplist在内存中各部分依次为
zlbytes zltail zlen <entry1, entry2, entryn> zlend:255
entry: prerawlen len data
含义:
zlbytes:32bit,表示ziplist占用的字节总数;
zltail:32bit,表示ziplist表中的最后一项,在ziplist中的偏移字节数,通过ziptail可以快速找到最后一项,从而可以快速在list尾部执行push或pop操作;
zlen:16bit,表示ziplist中数据项个数;
zend:8bit,ziplist最后一个字节,是一个结束标记,值固定为255;
entry:表示真正存放数据的数据项,长度不定;
prerawlen:表示前一个数据项数据长度,当长度小于254,则用一个字节表示;否则用一个值为254的字节标记 + 4个字节表示真实长度,加起来即5个字节。
len:数据项长度;
data:真实数据存储,根据len值不同,共有13种情况。

ziplist优点

Redis对内存敏感,连续紧凑的数据结构能节省内存。

ziplist缺点

当需要往链表中间插入数据,要对部分数据进行迁移,进行大量内存分配,数据量大的时候效果不好。

优化

使用quicklist,对ziplist进行分段。
quicklist内存结构
head - tail - count - length
head: 指向quicklist的头结点,指针为quicklistNode;
tail:指向quicklist的尾结点,指针为quicklistNode;
count:quicklist中ziplist个数
length:quicklist中ziplist个数

quicklistNode: prev - next - zl - length
prev:指向前一个quicklistNode;
next:指向下一个quicklistNode;
zl:指向ziplist地址;
length:ziplist元素个数;

配置

设置每个ziplist容量大小,-2代表容量为8kb

# Lists are also encoded in a special way to save a lot of space.
# The number of entries allowed per internal list node can be specified
# as a fixed maximum size or a maximum number of elements.
# For a fixed maximum size, use -5 through -1, meaning:
# -5: max size: 64 Kb  <-- not recommended for normal workloads
# -4: max size: 32 Kb  <-- not recommended
# -3: max size: 16 Kb  <-- probably not recommended
# -2: max size: 8 Kb   <-- good
# -1: max size: 4 Kb   <-- good
# Positive numbers mean store up to _exactly_ that number of elements
# per list node.
# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
# but if your use case is unique, adjust the settings as necessary.
list-max-ziplist-size -2

设置quicklist数据压缩范围,提升数据存储效率

# Lists may also be compressed.
# Compress depth is the number of quicklist ziplist nodes from *each* side of
# the list to *exclude* from compression.  The head and tail of the list
# are always uncompressed for fast push/pop operations.  Settings are:
# 0: disable all list compression
# 1: depth 1 means "don't start compressing until after 1 node into the list,
#    going from either the head or tail"
#    So: [head]->node->node->...->node->[tail]
#    [head], [tail] will always be uncompressed; inner nodes will compress.
# 2: [head]->[next]->node->node->...->node->[prev]->[tail]
#    2 here means: don't compress head or head->next or tail->prev or tail,
#    but compress all nodes between them.
# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
# etc.
list-compress-depth 0

默认设置为0,表示所有数据都不压缩,当设置为1时,表示头尾两个quicklistNode不压缩,其他压缩;
当设置为2时,表示头两个和尾部两个quicklistNode不压缩,其他压缩;
因为list常用于存储热点数据,比较关注头尾数据,中间数据较少关注,可以进行压缩。

相关文章

  • redis list底层数据结构

    redis list数据结构  redis list数据结构底层采用压缩列表ziplist或linkedlist两...

  • Redis 中List 及 quicklist实现 1

    quicklist是在Redis 3.2 之后出现的一种Redis底层数据结构用于List结构的具体实现,List...

  • redis

    Redis的List用过吗?底层怎么实现的?知道但是没用过,不知道怎么实现 Redis基本数据结构 String(...

  • Redis对象(一) - 类型和编码

    对象 前边学习了Redis底层实现的各种数据结构, 包括SDS, list, skiplist, dict, in...

  • t_list.c

    Redis的t_list.c是对list数据结构的实现。在Redis3.2之前,list数据结构基于ziplist...

  • Redis' lists

    Redis列表基本操作命令 Redis list底层结构 Redis list由链表来实现。在Redis中链表的应...

  • web编程进阶(二)

    请问redis的List能在什么场景下使用? 考察点:redis参考回答: Redis 中list的数据结构实现是...

  • 吊打面试官之 Java Web [3]

    1.请问redis的List能在什么场景下使用? 参考回答: Redis 中list的数据结构实现是双向链表,所以...

  • Redis - list底层数据结构实现

    前言 List是一个按加入时序排序的数据结构,Redis采用quicklist(双端链表) + ziplist 作...

  • redis底层数据实现及应用场景

    redis数据类型及底层实现 redis全局哈希表 String 底层数据结构: 简单动态字符串 应用场景: 缓存...

网友评论

      本文标题:Redis - list底层数据结构实现

      本文链接:https://www.haomeiwen.com/subject/whiekltx.html