Redis学习笔记 ——(4)列表的用法、内部编码、使用场景
列表类型是用来存储多个有序的字符串,在redis里,可以对列表两端插入和弹出,还可以取出指定范围的元素列表,获取指定索引下标的元素,列表是一个比较灵活的数据结构,它可以戳你高档栈和队列的角色。
特点
- 有序的
列表的元素是有序的,这样就可以通过索引的下表获取指定范围内的元素。 - 可重复的
列表中的元素可以重复
命令
测试命令,左边插入dog,cat,右边插入pig, 最后查看,可以看到左边显示dog插入,然后cat再次插入,最后在右边插入pig,形成 cat、dog、pig的顺序。
127.0.0.1:6379> lpush my_list dog
(integer) 1
127.0.0.1:6379> lpush my_list cat
(integer) 2
127.0.0.1:6379> rpush my_list pig
(integer) 3
127.0.0.1:6379> lrange my_list 0 3
1) "cat"
2) "dog"
3) "pig"
- BLPOP key1 [key2 ] timeout
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 - BRPOP key1 [key2 ] timeout
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 - BRPOPLPUSH source destination timeout
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 - LINDEX key index
通过索引获取列表中的元素 - LINSERT key BEFORE|AFTER pivot value
在列表的元素前或者后插入元素 - LLEN key
获取列表长度 - LPOP key
移出并获取列表的第一个元素 - LPUSH key value1 [value2]
将一个或多个值插入到列表头部 - LPUSHX key value
将一个值插入到已存在的列表头部 - LRANGE key start stop
获取列表指定范围内的元素 - LREM key count value
移除列表元素 - LSET key index value
通过索引设置列表元素的值 - LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 - RPOP key
移除列表的最后一个元素,返回值为移除的元素。 - RPOPLPUSH source destination
移除列表的最后一个元素,并将该元素添加到另一个列表并返回 - RPUSH key value1 [value2]
在列表中添加一个或多个值 - RPUSHX key value
为已存在的列表添加值
内部编码
列表类型的内部编码有两种
- ziplist
hash元素个数小于list-max-ziplist-entries(默认512) - linkedlist
当列表类型无法满足ziplist条件时,Redis会使用linkedlist作为列表的内部实现。
使用场景
不同的操作组合可以构成多种数据类型
lpush + lpop = Stack 栈
lpush + rpop = Queue 队列
plush + ltrim = capped collection 有限集合
lpush + brpop = message queue 消息队列
-
消息队列
Redis的lpush+brpop命令的组合可以实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的抢烈火表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
-
文章列表
每个用户都拥有自己的文章列表,先需要分页展示文章列表,此时可以考虑使用列表,因为列表是有序的,同时可以按照索引范围获取元素。
使用列表类型保存和获取文章列表会存在两个问题。
第一,如果每次分页获取的文章个数较多,需要执行需要多次hgetall操作,此时可以使用Pipeline批量获取,或者将文章数据序列化为字符串数据,使用mget批量获取。
第二,分页获取文章列表是,lrange命令在列表两端性能较好,如果列表较大,获取列表中间范围的元素性能也会变差,此时可以考虑将列表做二级拆分,或使用quicklist内部编码实现,它结合ziplist和linkedlist的特点,获取列表中间范围的元素是也可以高效实现。