Redis数据类型-List

本文记录Redis学习过程中遇到的Redis数据类型-List~

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295。

从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而,需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。

ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位操作,所以比较慢;
LinkedList使用双向链接方式存储数据,每个元素都记录前后元素的指针,所以插入和删除数据时只是更改前后元素的指针指向,速度非常快,然后通过下标查询元素时需要从头开始索引,所以比较慢。

常用命令:

  • lpush key values[value1 value2...]:在指定的key所关联的list的头部插入所有的values。如果该key不存在,该命令在插入之前创建一个与该key关联的空链表,之后再向该链表的头部插入数据。插入成功后,返回元素的总个数;
  • rpush key values[value1 value2...]:在List的尾部插入元素,其他与rpush相同;
  • lrange key start end:获取链表中从start到end的元素的值,start和end从0开始计数;也可为负数,若为-1则表示链表尾部的元素,-2则表示倒数第二个,依次类推;
  • lpop key:返回并弹出指定的key关联的链表中的第一个元素,即头部元素。如果该key不存在,返回nil;若key存在,则返回链表的头部元素;
  • rpop key:从尾部弹出元素,其余与lpop相同;
  • llen key:返回指定的key关联的链表中的元素的数量;
  • lpushx key:仅当参数中指定的key存在时,向关联的list的头部插入value。如果不存在,将不进行插入;
  • rpushx key:在该list的尾部添加元素,其余与lpushx相同;
  • lrem key count value:删除count个值为value的元素。如果count大于0,从头到尾遍历并删除count个值为value的元素;如果count小于0,则从尾到头遍历删除;如果count等于0,则删除链表中所有等于value的元素;
  • lset key index value:设置链表中的index的脚标的元素值,0代表链表的头元素,-1代表链表的尾元素,操作链表的脚标不存在则抛异常;
  • linsert key before|after pivot value:在pivot元素前或后插入value这个元素;
  • rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部(循环操作);

示例代码:

lpush mylist a b c
lpush mylist 1 2 3
rpush mylist 4 5 6
lrange mylist 0 -1
lpop mylist
rpop mylist
llen mylist
lpushx mylist 1
rpushx mylist c
lrem mylist 0 a
lset mylist 0 a
linsert mylist after 0 abc
rpoplpush mylist1 mylist2

rpoplpush的使用场景:

Redis链表经常会被用于消息队列的服务,以完成多程序之间的消息交换。假设一个应用程序正在执行lpush操作向链表中添加新的元素,我们通常将这样的程序称之为“生成者”,而另外一个应用程序正在执行rpop操作从链表中取出元素,我们称这样的程序为“消费者”。如果此时,消费者程序在取出消息元素后立刻崩溃,由于该消息已经被取出且没有被正常处理,那么我们就可以认为该消息已经丢失,由此可能会导致业务数据丢失,或业务状态的不一致等现象等发生。然而通过rpoplpush命令,消费者程序在从主消息队列中取出消息之后再将其插入到备份队列中,直到消费者程序完成正常的处理逻辑后再将该消息从备份队列中删除。同时我们还可以提供一个守护进程,当发现备份队列中的消息过期时,可以重新将其再放回到主消息队列中,以便其他的消费者程序继续处理。

标签: none