1、简介
列表(list)类型是用来存储多个有序的字符串的,列表中每个字符串成为元素,一个列表最多可以存储2^32-1个元素。在Redis中可以对列表的两端插入(push)和读取(pop),还可以获取指定范围内的元素列表,获取指定索引下标的元素,是一种十分灵活的数据结构,它可以充当队列和栈的角色,在实际开发中十分有用。
2、常用命令
(1)添加
1)从右边插入
rpush key value [value ...]
示例:
127.0.0.1:6379> rpush list1 a b c d
(integer) 4
#查询结果
127.0.0.1:6379> lrange list1 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
2)从左边插入
lpush key value [value ...]
示例:
127.0.0.1:6379> lpush list2 a b c d
(integer) 4
3)向某个元素前或者后添加元素
linsert key before|after pivot value
linsert 命令会从列表中找到pivot元素,然后在其前(before)或后(after)插入一个新的元素value。
示例:
127.0.0.1:6379> linsert list1 before a xx
(integer) 5
#查询结果
127.0.0.1:6379> lrange list1 0 -1
1) "xx"
2) "a"
3) "b"
4) "c"
5) "d"
(2)查找
1)获取指定范围内的元素列表
lrange key start end
lrange操作会获取列表指定索引范围所有的元素。索引下标有两个特点:第一:索引下标从左到右分别是0到n-1,但是从右往左是-1到-n,第二:lrange中的end选项包含了自身。
2)获取列表指定索引下标的元素
lindex key index
3)获取列表长度
llen key
(3)删除
1)从列表左侧弹出元素
lpop key
2)从列表右侧弹出元素
rpop key
3)删除指定元素
lrem key count value
lrem命令会从列表中找到等于value的元素删除,根据count的不同分为三种情况。
- count>0 从左往右,删除最多count个元素
- count<0 从右往左,删除最多count的绝对值个元素
- count=0 删除所有
3)按照索引范围修剪列表
ltrim key start end
ltrim命令只会保留列表中第start+1到第end+1个元素
(4)修改
修改指定索引下标的元素
lset key index newValue
(5)阻塞
blpop key [key ...] timeout
brpop key [key ...] timeout
blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同。blpop和brpop命令包含两个参数:
- key [key …]:多个列表的键
- timeout :阻塞时间(单位:秒)
1)列表为空时,如果timeout = 2 ,那么客户端2秒以后返回,如果timeout = 0,那么客户端会一直阻塞下去,在阻塞期间如果添加了数据,客户端会立即返回添加的数据。
2) 列表不为空时,客户端会立即返回。
注意:
在使用brpop时,有两点需要注意:
1)如果是多个键,那么brpop会从左往右遍历,一旦有一个键能弹出元素,客户端立即返回。例如:
127.0.0.1:6379> brpop list1 list2 list3 0
#阻塞状态 ...
#此时另一个客户端分别向list2和list3插入数据,客户端会立即返回list2中的数据,因为list2是最先有数据弹出的。
2)如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取到弹出的值。
3、内部编码
列表类型的内部编码有三种:
- ziplist(压缩列表):
当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时所有值都小于list-maxziplist-value配置(默认为64字节),Redis会使用ziplist做为列表的内部实现。Ziplist可以使用更加紧凑的结构来实现多个元素的连续存储,所以在节省内存方面更加优秀。 - linkedlist(链表):
当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现 - quicklist(快速列表):
从Redis3.2版本以后,加入的新的数据结构。简单讲,它是以ziplist为节点的linkedlist,结合了ziplist和linkedlist的优点,具有双向链表的优点,进行插入和删除操作时非常方便。
4、使用场景
(1)消息队列
Redis的lpush+brpop命令组合即可实现阻塞队列,生产者使用lpush从列表的左侧插入消息,多个消费者使用brpop命令阻塞式的 消费列表尾部的消息,多个 客户端保证了消费的负载均衡和高可用性。
(2)数据列表
数据分页展示的应用,比如文章或博客网站的数据列表信息,当用户量越来越大的时候,每一个用户都有自己的数据列表信息,而且当文章很多时,都需要分页展示,这是可以考虑使用redis列表,不但可以有序,同时还支持按照范围获取元素,可以完美解决分页查询,大大提高查询效率。
(3)使用策略
- lpush + lpop = Stack(栈)
- lpush + rpop = Queue(队列)
- lpush + ltrim = Capped Collention(有限集合)
- lpush + brpop = Message Queue(消息队列)