Redis初识第五期---List的命令和使用场景
List,相当于数组或者顺序表,List对元素顺序敏感,允许元素重复,这是和后面的Set类型来对比的,但是得益于Redis对List的优化,使得它支持头/尾插/删,使得List也可以作为一个栈/队列来使用。
命令
普通版本命令
1.LPush
LPush key element [element.....]
头插,可以同时插入多个元素,最后一个元素在最前面。
返回的为list的长度,可以为key为空的插入元素。
2.Lrange
Lrange key start stop(闭区间),同时Redis也支持负数下标。
查看List中指定范围的元素。当下标越界时,Redis会将下标中所有的元素都拿出来,并不会报错。
3.LpushX
只有key存在才会插入,不存在则直接返回,语法和Lpush一样。
4.Rpush
在右侧(尾部)插入元素,也可以一次插入多个
5.RpushX
和LpushX一样,也是在key存在时才插入。
6.Lpop
头删,返回被删除元素的值,如果没有元素,就返回nil。
7.Rpop
尾删,和Lpop语法一样。
以上两个命令在Redis6.2以后引入了count属性,即可以指定删除的元素的个数。
8.Lindex
根据下标获取元素,时间复杂度为O(n),支持负数下标。
语法:Lindex key index
非法下标会返回nil。
9.Linsert
插入元素至指定的位置,时间复杂度也是O(n)
Linsert key <before/after> pivot element
pivot:基准元素,为具体的值。
<before/after>:插入到基准元素的前/后
如果基准元素有多个时,只会插入到第一个基准元素的前/后。
10.Llen
Llen key
获取key元素的长度。
11.LRem
LRem key count element
count:删除个数
element:要删除的值
时间复杂度为O(n);
当count>0,从左往有删除count个element。
count<0,从右往左,删除count个element。
count==0,删除所有的element。
12.LTrim
Ltrim key start stop(闭区间)
只保留start到stop之间的元素,其他的全删了。
13.Lset
Lset key index element
将指定下标的元素改为element。(这个下标越界会报错)
阻塞版本命令
14.blpop,brpop
当list中存在元素,brpop和blpop和lpop和rpop作用一样,但list元素为空时,blpop和brpop会阻塞,一直到对列不为空,设置最大阻塞时间来避免死等,时间单位为s。0的话为无限等待。
值得注意的是,在brpop和blpop阻塞期间,Redis是可以执行其他任务的。
同时,若多个客户端同时执行一个键的pop,则最先执行命令的客户端会得到元素。
brpop和blpop也可以同时获取多个key的列表的元素,这些list中哪个有元素了就返回哪个。
这些操作使得List可以作为一个简单的消息队列:
1.线程安全通过Redis本身的单线程来保证。
2.由于List容量较大,所以只有blpop和brpop,没有阻塞版本的插入。
List内部编码
ziplist(Redis3.2以前)
压缩列表,前面已经介绍过了,主要就是减少内存空间占用,但是会让操作变慢,适用于元素个数少,元素长度较短的情况。
linkedlist:就是普通的链表。
Redis3.2以后:
qickList:结合了zipList和linkedlist的优点,整体为一个链表,但是链表的每一个节点为一个ziplist同时控制zipist不让它过大。
List的应用场景
用List作为数组来存多个元素
和Hash类似,但是通过将Mysql中的数据转化为key-value的形式。
使用Redis作为消息队列
这个上面已经指出了,但是这个消息队列很粗糙,功能也很少。
分频道阻塞消息队列
举一个实例,抖音的视频可以看弹幕,看评论,还可以点赞,如果这些功能都用一个频道实现,那频道出错后,这个视频就都完了,如果搞成多个频道,某一个出问题,其他的还能继续使用(低耦合)。
其次由于List对元素位置敏感,可以使用这个特性来按照时间线存储,例如微博就是使用List来按照时间线来获取最新微博的。