4、列表
列表(list)类型是用来存储多个有序的字符串,如图2-18所示,a、b、c、d、e五个元素从左到右组成一个有序列表,列表中的每个字符串称为元素,一个列表最大可以存储2^32-1个元素。在Redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等(如图2-18和图2-19所示)。列表是一种比较灵活的数据结构,它可充当栈和队列的角色,在实际开发中有很多应用场景。
列表类型有如下两个特点:
(1)列表中的元素是有序的。这就意味着可以通过索引下表获取某个元素或者某个范围内的元素列表,例如要获取图2-19的第5个元素,可以执行lindex user:1: message4 (索引从0开始)就可以得到元素e。
(2)列表中的元素可以是重复的。例如图2-20所示列表中包含两个字符串a。
4.1 命令
按照对列表的5种操作类型对命令进行介绍,命令如表2-4所示。
4.1.1 添加操作
(1)从右边插入元素
1 rpush key value [value ...]
程序举例:
可以使用 lrange 0 -1 命令从左到右获取列表中的所有元素。
(2)从左边插入元素
1 lpush key value [value ...]
使用方法和rpush相同,只不过从左侧插入。
(3)向某个元素前或者后插入元素
1 linsert key before | after pivot value
linsert命令会从列表中找出等于pivot的元素,在其前(before)护着后(after)插入新的元素value,例如下面的操作会在列表的元素b前插入java:
返回结果为4,代表当前命令的长度,可使用lrange命令查看当前列表。
4.1.2 查找
(1)获取指定范围内的元素列表
1 lrange key start end
lrange操作会获取列表指定索引范围所有的元素。索引下表有2个特点:
- 索引下标从左到右分别是0到N-1,但是从右到左分别是-1和-N。
- lrange中的end选项包含了自身,这和很多编程语言是不同的。
例如想获取列表的第2到第4个元素,可以执行下列操作:
(2)获取列表指定索引下表的元素
1 lindex key index
例如当前列表最后一个元素为a:
(3)获取列表长度
1 llen key
例如下面示例当前列表长度为4:
4.1.3 删除
(1)从列表左侧弹出元素
1 lpop key
如下操作会将列表最左侧的元素a弹出,弹出后列表变为java、b、c
(2)从列表右侧弹出元素
1 rpop key
(3)删除指定元素
1 lrem key count value
lrem命令会从列表中找到等于value的元素并进行删除,根据count的不同分为3种情况:
- count > 0 ,从左到右最多删除count个元素;
- count < 0 ,从右到左最多删除count绝对值个元素;
- count = 0 ,删除所有。
例如下述操作从列表左边开始删除4个为a的元素:
(4)按照索引范围修剪列表
1 ltrim key start end
例如下述操作只保留了listkey列表中的第2到第4个元素:
4.1.4 修改
修改指定索引下标的元素:
1 lset key index newValue
下面的操作会将列表listkey中的第3个元素设置为python:
4.1.5 阻塞操作
4.2 内部编码
列表类型的内部编码有2种:
- ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认为512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),redis会选用ziplist来作为列表内部实现来减少内存的使用。
- linkedlist(链表):当列表类型无法满足ziplist的条件时,redis会使用linkedlist作为列表的内部实现。
4.3 使用场景
4.3.1 消息队列
如图2-21所示,redis的lpush+brpop命令组合可以实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费者的负载均衡以及高可用性。