Redis列表对象是简单的字符串列表,按照插入顺序排序,可以添加一个元素到头部或尾部,一个列表键最多可包含2^32-1个元素。
1. 编码
Redis列表键的底层编码是QUICKLIST,而quicklist本质上就是以ziplist为结点的双端链表。
2. 命令
| 命令 | 作用 |
|---|---|
| LINDEX | 根据索引index获取列表key中的元素 |
| LINSERT | 在列表key指定的元素pivot的前/后插入元素 |
| LLEN | 获取列表key的长度 |
| LPOP | 从列表key中移除第一个元素 |
| LPUSH | 在列表key中的头部插入一个或多个元素 |
| LPUSHX | 插入一个元素value到已经存在的列表key |
| LRANGE | 获取列表key指定范围start,end的元素 |
| LREM | 移除列表元素 |
| LSET | 通过索引index设置列表中的元素 |
| LTRIM | 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 |
| RPOP | 移除并获取列表最后一个元素 |
| RPOPLPUSH | 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 |
| RPUSH | 在列表中添加一个或多个值 |
| RPUSHX | 为已存在的列表添加值 |
3. 阻塞命令
Redis定义了阻塞状态,而每个客户端都有这样的一个状态。
1 | typedef struct blockingState { |
blocking_keys
保存处于阻塞状态key的字典,每个key都是一个阻塞的键,而值是一个双端链表,表示被这个key所阻塞的客户端
bpop.keys
bpop是每个客户端保存的阻塞状态结构,其中key表示的是造成这个客户端阻塞的键。
| 命令 | 作用 |
|---|---|
| BLPOP | 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
| BRPOP | 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
| BRPOPLPUSH | 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
4. 源码剖析
- 阻塞客户端
1 | void blockForKeys(client *c, robj **keys, int numkeys, mstime_t timeout, robj *target) { |
- 解除阻塞
1 | /** |
- PUSH命令底层实现
1 | void pushGenericCommand(client *c, int where) { |
- POP命令底层实现
1 | void popGenericCommand(client *c, int where) { |