redis列表(List)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

实例:

redis 127.0.0.1:6379> LPUSH catroomkey redis
(integer) 1
redis 127.0.0.1:6379> LPUSH catroomkey mongodb
(integer) 2
redis 127.0.0.1:6379> LPUSH catroomkey mysql
(integer) 3
redis 127.0.0.1:6379> LRANGE catroomkey 0 10
1) "mysql"
2) "mongodb"
3) "redis"

在以上实例中使用了 LPUSH 将三个值插入了名为 catroomkey 的列表当中。Redis list(列表)相当于 Java 语言中的 LinkedList 结构,是一个链表而非数组,其插入、删除元素的时间复杂度为 O(1),但是查询速度欠佳,时间复杂度为 O(n)。当向列表中添加元素值时,首先需要给这个列表指定一个 key 键,然后使用相应的命令,从列表的左侧(头部)或者右侧(尾部)来添加元素,这些元素会以添加时的顺序排列。一个列表最多可以包含 2^32 - 1 个元素(约 40 亿个元素),当列表弹出最后一个元素时,该结构会被自动删除。



Redis list实现原理

Redis 列表的底层存储结构,其实是一个被称为快速链表(quicklist)的结构。当列表中存储的元素较少时,Redis 会使用一块连续的内存来存储这些元素,这个连续的结构被称为 ziplist(压缩列表),它将所有的元素紧挨着一起存储。

压缩列表是 Redis 为节省内存而开发的,它是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表了可以包含任意多个节点,每个节点都可以保存一个字符数组或者整数值。

而当数据量较大时,Redis 列表就会是用 quicklist(快速链表)存储元素。Redis 之所以采用两种方法相结合的方式来存储元素。这是因为单独使用普通链表存储元素时,所需的空间较大,会造成存储空间的浪费。因此采用了链表和压缩列表相结合的方式,也就是 quicklist + ziplist,结构如下图:
redis列表结构

如上图 1 所示,将多个 ziplist 使用双向指针串联起来,这样既能满足快速插入、删除的特性,又节省了一部分存储空间。

常用的List命令演示

#从左侧头部插入元素
127.0.0.1:6379> LPUSH catroom python
(integer) 1
127.0.0.1:6379> LPUSH catroom java c c#
(integer) 4
#查看插入的元素
127.0.0.1:6379> LRANGE catroom 0 4
1) "c#"
2) "c"
3) "java"
4) "python"
#从右侧尾部插入元素
127.0.0.1:6379> RPUSH catroom "Math"
(integer) 5
127.0.0.1:6379> RPUSH catroom "Computer Language"
(integer) 6
#查看元素
127.0.0.1:6379> LRANGE catroom 0 6
1) "c#"
2) "c"
3) "java"
4) "python"
5) "Math"
6) "Computer Language"
#在python前面插入元素
127.0.0.1:6379> LINSERT catroom BEFORE python Python
(integer) 7
#从左侧弹出元素
127.0.0.1:6379> LPOP catroom
"c#"
#从右侧弹出元素
127.0.0.1:6379> RPOP catroom
"Computer Language"

Redis实现队列和栈

Redis 列表可以被当做栈、队列来使用,如果列表的元素是“左进右出”那就是队列模型;如果元素是“右进右出”那就是栈模型,示例如下:

1) 右进左出
127.0.0.1:6379> Rpush book c python java
(integer) 3
127.0.0.1:6379> lpop book
"c"
127.0.0.1:6379> lpop book
"python"
127.0.0.1:6379> lpop book
"java"
127.0.0.1:6379> lpop book
(nil)
2) 右进右出
127.0.0.1:6379> RPUSH book  c python java
(integer) 3
127.0.0.1:6379> rpop book
"java"
127.0.0.1:6379> rpop book
"python"
127.0.0.1:6379> rpop book
"c"
127.0.0.1:6379> rpop book
(nil)

redis List相关的常用命令

  • LPUSH key value1 [value2]
    在列表头部插入一个或者多个值。
  • LRANGE key start stop
    获取列表指定范围内的元素。
  • RPUSH key value1 [value2]
    在列表尾部添加一个或多个值。
  • LPUSHX key value
    当储存列表的 key 存在时,用于将值插入到列表头部。
  • RPUSHX key value
    当存储列表的 key 存在时,用于将值插入到列表的尾部。
  • LINDEX key index
    通过索引获取列表中的元素。
  • LINSERT key before|after pivot value
    指定列表中一个元素在它之前或之后插入另外一个元素。
  • LREM key count value
    表示从列表中删除元素与 value 相等的元素。count 表示删除的数量,为 0 表示全部移除。
  • LSET key index value
    表示通过其索引设置列表中元素的值。
  • LTRIM key start stop
    保留列表中指定范围内的元素值。
  • LPOP key
    从列表的头部弹出元素,默认为第一个元素。
  • RPOP key
    从列表的尾部弹出元素,默认为最后一个元素。
  • LLEN key
    用于获取列表的长度。
  • RPOPLPUSH source destination
    用于删除列表中的最后一个元素,然后将该元素添加到另一个列表的头部,并返回该元素值。
  • BLPOP key1 [key2 ] timeout
    用于删除并返回列表中的第一个元素(头部操作),如果列表中没有元素,就会发生阻塞,直到列表等待超时或发现可弹出元素为止。
  • BRPOP key1 [key2 ] timeout
    用于删除并返回列表中的最后一个元素(尾部操作),如果列表中没有元素,就会发生阻塞, 直到列表等待超时或发现可弹出元素为止。
  • BRPOPLPUSH source destination timeout
    从列表中取出最后一个元素,并插入到另一个列表的头部。如果列表中没有元素,就会发生阻塞,直到等待超时或发现可弹出元素时为止。
    参考:更多全面的redis教程