list取值_深入学习Redis(四),基本类型【List】剖析

2699e5b9f2e2e63930153b3173e4b71a.png

接下来我们要剖析的基本类型是List,相信大家对List都不会陌生吧,下面我们将深入源码剖析RedisList的实现。

存储类型

存储有序的字符串(从左到右),元素可以重复。可以充当队列和栈的角色。

7345ae761316764abf3bff8c2b146cc6.png

操作命令

元素增减

lpush queue a
lpush queue b c
rpush queue d e
lpop queue
rpop queue
​blpop queue
brpop queue

取值

lindex queue 0
lrange queue 0 -1

8b2ff8d9affa847cd6852b8ff39852fc.png

java架构师:作为Java开发,我是如何在一年之内,让自己的月薪爆炸式提升!!​zhuanlan.zhihu.com

f381a152b7c4bb82e0115c3375e4825e.png

存储( 实现) 原理

在早期的版本中,数据量较小时用 ziplist 存储,达到临界值时转换为 linkedlist 进

行存储,分别对应 OBJ_ENCODING_ZIPLIST 和 OBJ_ENCODING_LINKEDLIST 。

3.2 版本之后,统一用 quicklist 来存储。quicklist 存储了一个双向链表,每个节点

都是一个 ziplist

127.0.0.1:6379> object encoding queue
"quicklist"
什么是quicklist?

quicklist(快速列表)是 ziplist 和 linkedlist 的结合体。

quicklist.h源码如下,head 和 tail 指向双向列表的表头和表尾

typedef struct quicklist {
  quicklistNode *head; /* 指向双向列表的表头 */
  quicklistNode *tail; /* 指向双向列表的表尾 */
  unsigned long count; /* 所有的 ziplist 中一共存了多少个元素 */
  unsigned long len; /* 双向链表的长度, node 的数量 */
  int fill : 16; /* fill factor for individual nodes */
  unsigned int compress : 16; /* 压缩深度, 0: 不压缩; */
} quicklist;

redis.conf 相关参数:

list-max-ziplist-size(fill)

正数表示单个 ziplist 最多所包含的 entry 个数。

负数代表单个 ziplist 的大小, 默认 8k。

-1: 4KB; -2: 8KB; -3: 16KB; -4: 32KB; -5: 64KB

list-compress-depth(compress)

压缩深度, 默认是 0。

其它值含义: 1: 首尾的 ziplist 不压缩; 2: 首尾第一第二个 ziplist 不压缩, 以此类推

quicklistNode 中的*zl 指向一个 ziplist,一个 ziplist 可以存放多个元素。

源码如下:

typedef struct quicklistNode {
  struct quicklistNode *prev; /* 前一个节点 */
  struct quicklistNode *next; /* 后一个节点 */
  unsigned char *zl; /* 指向实际的 ziplist */
  unsigned int sz; /* 当前 ziplist 占用多少字节 */
  unsigned int count : 16; /* 当前 ziplist 中存储了多少个元素, 占 16bit(下同) , 最大 65536 个 */
  unsigned int encoding : 2; /* 是否采用了 LZF 压缩算法压缩节点, 1: RAW 2: LZF */
  unsigned int container : 2; /* 2: ziplist, 未来可能支持其他结构存储 */
  unsigned int recompress : 1; /* 当前 ziplist 是不是已经被解压出来作临时使用 */
  unsigned int attempted_compress : 1; /* 测试用 */
  unsigned int extra : 10; /* 预留给未来使用 */
} quicklistNode;

943029fda7198cd35a5cf227b7a90b46.png
源码结构图

ziplist 的结构前面已经说过了,不再重复,请移步。

应用场景

用户消息时间线 timeline

因为 List 是有序的,可以用来做用户时间线

ae8f72dcb1455c8528db35e5eae60185.png

消息队列

List 提供了两个阻塞的弹出操作:BLPOP/BRPOP,可以设置超时时间。

BLPOPBLPOP key1 timeout 移出并获取列表的第一个元素, 如果列表没有元素

会阻塞列表直到等待超时或发现可弹出元素为止。

BRPOP:BRPOP key1 timeout 移出并获取列表的最后一个元素, 如果列表没有元

素会阻塞列表直到等待超时或发现可弹出元素为止。

队列:先进先出:rpush blpop,左头右尾,右边进入队列,左边出队列。

栈:先进后出:rpush brpop

今天我们从底层源码剖析了基本数据类型List,接下来我们将会对剩下的几个常用的基本类型的深入探讨,敬请期待。

java架构师:作为Java开发,我是如何在一年之内,让自己的月薪爆炸式提升!!​zhuanlan.zhihu.com

f381a152b7c4bb82e0115c3375e4825e.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值