您的位置:首页 > 理论基础 > 数据结构算法

Redis 数据结构 列表(四)

2018-06-29 14:24 169 查看

1、一个列表最多可以存储2^32 -1 个元素,列表是一个灵活的数据结构,它可以从两端插入(push)和弹出(pop),它可以充当栈和消息队列。

2、列表中的元素是有序的,这就意味着可以通过索引获取某个元素或某个范围内的元素。并且列表中的元素可以重复。

一、命令

1、添加操作

     1) 从右向左插入

        rpush key  value [value ...]

 

127.0.0.1:6379> rpush list 1 2 3

(integer) 1

127.0.0.1:6379> lrange list 0 -1

1) "1,2,3"

127.0.0.1:6379> 

 

      2)从左向右插入

 

        lpush key  value [value ...]

 

127.0.0.1:6379> lpush list2 3 2 1

(integer) 3

 

127.0.0.1:6379> lrange list2 0 -1

1) "1"

2) "2"

3) "3"

127.0.0.1:6379> 

 

      3)向某个元素前或者后插入数据

        linsert key befort/after pivot value

        linsert 命令会去找第一个pivot的元素,在其前或者后插入一个新的元素value

2、查找

    1)获取制定范围内的元素列表

        lrange key start end

    lrange操作会获取列表指定索引范围内的所有元素。索引下标有两个特点,第一,索引小标从左往右分别是0 ~ N-1,但是从右到左分别是-1到-N;第二,lrange中的end选项包含了自身,即包左又包右。

 

127.0.0.1:6379> lrange list2 0 -1

1) "0"

2) "1"

3) "-1"

4) "1"

5) "2"

6) "3"

 

2)获取列表指定索引下标的元素

 

    lindex  key index

 

//获取最后一个元素:

127.0.0.1:6379> lindex list2 -1

"3"

 

3)获取列表长度

    llen key 

 

127.0.0.1:6379> llen list2

(integer) 6

 

 

 

3、删除

1)   lpop key   从左侧弹出,返回弹出的值

2)   rpop key  从右侧弹出,返回弹出的值

 3)  删除指定元素

      lrem  key  count  value

            lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况

            count > 0 ,从左往右,删除最多count个元素

            count < 0 , 从右往左,删除最多个count绝对值个元素

            count = 0 , 删除所有。

4)按照索引范围修剪列表

     ltrim  key  start end 

 

127.0.0.1:6379> lrange list2 0 -1

1) "6"

2) "5"

3) "4"

4) "3"

5) "2"

6) "1"

127.0.0.1:6379> ltrim list2 1 3

OK

127.0.0.1:6379> lrange list2 0 -1

1) "5"

2) "4"

3) "3"

127.0.0.1:6379> 

 

4、修改

 

  修改指定索引下标的元素

   lset  key  index  newValue

 

127.0.0.1:6379> lrange list2 0 -1

1) "5"

2) "6"

3) "3"

127.0.0.1:6379> lset list2 0 9

OK

127.0.0.1:6379> lrange list2 0 -1

1) "9"

2) "6"

3) "3"

 

5、阻塞操作

 

    blpop  key [ key ...] timeout 

    brpop  key [key ...] timeout 

blpop和brpop是lpop和rpop的阻塞版本,他们除了弹出方向不同,使用方法基本相同。

  brpop包含两个参数:

        key  [key  ...]   多个列表的键

      timeout 阻塞时间(单位:秒)

    1)test列表为空,如果timeout=3,那么客户端要等到3秒后返回,如果为0,那么客户端一直阻塞下去,如果某一时刻另一个客户端push了一个test列表,则timeout为0的brpop立刻返回。

 

127.0.0.1:6379> brpop list 1

(nil)

(1.10s)

 

brpop如果是多个键,则会从左向右遍历,一旦有一个键能弹出元素,客户端立刻返回

如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取弹出的值

二、内部编码

    列表类型的内部编码有两种

   ziplist(压缩列表) :当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),redis会选用ziplist来作为列表的内部实现来减少内存的使用

linkedlist(链表):当列表类型无法满足ziplist的条件时,redis会使用linkedlist作为列表的内部实现

注:3.2版本给出quicklist内部编码,它是一个ziplist为节点的linkedlist,它结合了ziplist和linkedlist两者的优势,为列表类提供了一种更为优秀的内部编码实现,参考:https://matt.sh/redis-quicklist

三:使用场景

    1、消息队列

            Redis的lpush + brpop 命令组合即可实现阻塞队列,生产者客户端使用lpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部元素,多个客户端保证了消费的负载均衡和高可用性。

注:lrange命令在列表的两端性能较好,但是如果列表较大,获取列表中间范围的元素性能会变差,所以此时可以考虑列表做二级拆分。或使用quicklist内部编码实现。

          列表使用场景:

                    lpush + lpop  = Stack  (栈)

                    lpush +  rpop  = Queue (队列)

                    lupsh + brpop = Message Queue (消息队列)

                    lpush + ltrim  =Capped Collection (有限集合)

 

 

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: