Redis----List
List简介
List也是Redis类型五巨头之一,就是一个列表,你可以从列头和列尾操作它,顺序为你的插入顺序,可重复。
List的使用
- lpush key value : 向队列key的队头插入value
- rpush key value : 向队列key的队尾插入value
- lpop key : 从队列key取出队头元素
- rpop key : 从队列key取出队尾元素
- lrange key start stop : 取出列表key中从start到stop的的元素,从0开始
- lindex key index : 取出列表key中第index个的元素
- linsert key before/after value1 value2 : 向列表key的value1值之前或之后插入value2元素
- llen : 返回列表key的长度
- lrem key count value : 删除列表key中count个值为value的元素
- ltrim key start stop : 删除列表key中从start到stop之外的元素,从0开始
- lset key index value : 更新列表key中的第index个元素的值为value
- lpushx key value : 将value插入已存在的列表key中,列表key不存在则不操作
List的底层数据结构
在redis 3.2之前的版本,根据列表的大小(512)和存储的值大小(64byte)来决定底层的数据结构,ziplist ---> linkedlist。但是在之后的版本,redis优化了列表的底层数据存储结构,改为使用quicklist结构来存储列表。
quicklist的结构
/* quicklistNode is a 32 byte struct describing a ziplist for a quicklist.
* We use bit fields keep the quicklistNode at 32 bytes.
* count: 16 bits, max 65536 (max zl bytes is 65k, so max count actually < 32k).
* encoding: 2 bits, RAW=1, LZF=2.
* container: 2 bits, NONE=1, ZIPLIST=2.
* recompress: 1 bit, bool, true if node is temporarry decompressed for usage.
* attempted_compress: 1 bit, boolean, used for verifying during testing.
* extra: 12 bits, free for future use; pads out the remainder of 32 bits */
typedef struct quicklistNode {
//前驱节点
struct quicklistNode *prev;
//后继节点
struct quicklistNode *next;
// 保存的数据 压缩前ziplist 压缩后压缩的数据
unsigned char *zl;
// 压缩列表的大小
unsigned int sz;
// 压缩列表中元素个数
unsigned int count : 16;
// 编码方式 1 raw 2 lzf
unsigned int encoding : 2;
// 容器类型 1为none 2为压缩列表
unsigned int container : 2;
// 解压标记,当查看一个被压缩的数据时,需要暂时解压,标记此参数为1,之后再重新进行压缩
unsigned int recompress : 1;
// 节点是否因为太小不需要压缩
unsigned int attempted_compress : 1;
// 扩展字段
unsigned int extra : 10;
} quicklistNode;
/* quicklistLZF is a 4+N byte struct holding 'sz' followed by 'compressed'.
* 'sz' is byte length of 'compressed' field.
* 'compressed' is LZF data with total (compressed) length 'sz'
* NOTE: uncompressed length is stored in quicklistNode->sz.
* When quicklistNode->zl is compressed, node->zl points to a quicklistLZF */
typedef struct quicklistLZF {
// 压缩后长度
unsigned int sz;
// 压缩后的数据存放数组
char compressed[];
} quicklistLZF;
/* quicklist is a 32 byte struct (on 64-bit systems) describing a quicklist.
* 'count' is the number of total entries.
* 'len' is the number of quicklist nodes.
* 'compress' is: -1 if compression disabled, otherwise it's the number
* of quicklistNodes to leave uncompressed at ends of quicklist.
* 'fill' is the user-requested (or default) fill factor. */
typedef struct quicklist {
//头结点
quicklistNode *head;
//尾节点
quicklistNode *tail;
// quicklist中所有的压缩列表存储的entry数
unsigned long count;
// quicklist的链表节点的数量
unsigned int len;
// 负数代表级别,正数代表个数
int fill : 16;
// 压缩级别
unsigned int compress : 16; /* depth of end nodes not to compress;0=off *///压缩级别
} quicklist;
结构图示

quicklist的优化点
- 对比于单纯的ziplist,quicklist可以减少数据插入带来的联动更新次数,因为一个节点内的ziplist不会存太多的元素
- 对比于单纯的linkedlist,quicklist在单个node内部是ziplist的连续内存,节省空间和减少了内存碎片
其实quicklist很像java中的HashMap的数组+链表的结构,综合了ziplist和linkedlist的有点,在使用场景上这种组合是结合了两个的优点的。
列表list的应用场景
- 模拟消息队列,push和pop可以控制队列的进出顺序

浙公网安备 33010602011771号