[转帖]redis list类型介绍

redis,list,类型,介绍 · 浏览次数 : 0

小编点评

## Redis List类型介绍 **首先,我们必须理解List是哪一种数据结构?** List是一种链表,它是指一系列元素的线性序列。链表是一种线性数据结构,它由一系列节点组成,每个节点包含一个数据项和指向下一个节点的指针。 **然后,让我们来了解List的实现方式。** Redis 使用链表来实现List。链表是一种线性数据结构,它可以存储任何类型的数据。在Redis中,List也是链表的数据结构。 **List的优缺点** **优点:** * 快速插入元素 * 允许批量添加元素 * 支持排队操作 **缺点:** * 访问速度可能比数组慢 * 链表数据结构的插入操作开销很大 **最后,让我们总结List的用途:** * 用于存储大量的元素 * 用于实现生产者消费者模式 * 用于存储具有特定顺序的元素 **一些常用的Redis List操作命令:** | 命令 | 功能 | 示例 | |---|---|---| | LPUSH | 向列表中添加元素 | `LPUSH tasks 51)` | | RPOP | 从列表中取出元素 | `RPOP tasks` | | LTRIM | 从列表中删除元素 | `LTRIM mylist 0 2` | | BRPOP | 从列表中获取元素 | `BRPOP tasks 51)` | | BLPOP | 从列表中获取元素 | `BLPOP tasks 51)` |

正文

redis list类型介绍

要阐述redis的list数据类型,最好以一些理论开始,因为list术语在信息化众多技术中用的并不合适,如:
如Python中的list并不是链表结构,而是数组(同样的数据结构在Ruby语言中叫Array)。

以通常的观点来看,List仅仅是一个有序的元素序列:10,20,1,2,3就是一个序列。但是,由一个数组
数据结构实现List的属性与一个由链表数据结构实现的List的属性是有非常大的不同的。

redis的List是由链表实现的,这就意味着:即使你有数以百万记的元素要插入到redis的List中,但在List
头部或者尾部插入一个元素的操作所执行花费的时间是固定的,也就是说使用LPUSH命令在一个已含有10个元
素的List头部插入一个元素的速度与在一个已含有10000000元素的List头部插入一个元素的速度是一样的。

那么由链表实现又有什么缺陷呢?那就是访问速度。如果是由数组实现的List,可以通过索引快速访问List
中的元素(固定时间索引存取),如果是由链表实现的List,则访问List中元素开销与索引位置成比例。

Redis由链表实现主要是因为:对于数据库系统来说,能够向一个非常大的List中快速插入元素是非常关键的

Redis List的用法简单介绍

LPUSH命令用于在一个List头部添加一个新元素。RPUSH命令用于在一个List尾部添加一个新元素。

LRANGE命令用于返回List中指定范围的元素。

注:LRANGE命令用法:LRANGE key start stop,key为要操作的集合,start为开始偏移量,stop为结束偏移量
。偏移量为元素下标,0表示第一个元素,1表示第二个元素,也可以是负数,-1表示最后一个元素,-2表示倒数
第二个元素,以此类推。

>rpush mylist A
(integer) 1
>rpush mylist B
(integer) 2
>lpush mylist first
(integer) 3
>  lrange mylist 0 -1
1) "first"
2) "A"
3) "B"

    另外,LPUSH命令与RPUSH命令都支持批量添加,如:

    >rpush mylist 1 2 3 4 5 "foo bar"
    (integer)9
    >lrange mylist 0 -1
    1)"first"
    2)"A"
    3)"B"
    4)"1"
    5)"2"
    6)"3"
    7)"4"
    8)"5"
    9)"foo bar"
    

      Redis List的pop操作是操作List的一个重要操作,此操作既是检索操作,同时也是移除操作,并且既可以从头部也可以从尾部进行pop操w作。与添加元素命令相似,从头部弹出与从尾部弹出分别由命令LPOP和RPOP控制。

      >rpush mylist a b c
      (integer) 3
      >rpop mylist
      "c"
      >rpop mylist
      "b"
      >rpop mylist
      "a"
      >rpop mylist
      (nil)
      

        Redis返回null则表示List中已经没有元素了。

        Redis List 的通常使用场景

        Redis List对大量的任务都有用,如下是两种代表情况:

        • 记住用户发送到社交网络的最后更新

        • 使用生产者消费者模式的的进程间通信。生产者将数据推送到List,消费者(通常是worker)消费这些数据执行操作。Redis有特定的对List操作命令保证此种应用场景下使用Redis List的更高可靠性与高效性。

        例如,比较流行的Ruby的resque库和sidekip库在引擎底层使用Redis List来实现后台jobs。Twitter社交网站都是把用户发送的最新推文(tweets)放入Redis List。

        假如你的Home主页要展示一个照片分享社交网站发布的最近照片,并且想要快速的访问:

        • 每次当用户上传一张新的照片,我们使用命令LPUSH将照片的ID放入一个list。

        • 当用户访问Home主页时,我们使用LRANG 0 9命令来获取用户上传的最近10个照片。

        Capped lists

        在许多使用场景中,我们仅仅只想要使用List存储最近的数据,无论何种情况:社交网站更新、日志、或者其他任意场景。

        Redis允许用户将list作为限制集合使用,可以通过使用LTRIM命令仅仅记录最近N条数据,并删除其他的数据。

        LTRIM命令同LRANGE命令类似,但并不展示指定范围的元素,而是将指定范围内的元素作为新的集合元素并且将不在指定范围内的元素删除。如下

        >rpush mylist 1 2 3 4 5
        (integer) 5
        >ltrim mylist 0 2
        OK
        >lrange mylist 0 -1
        1)"1"
        2)"2"
        3)"3"
        

          上面的LTRIM命令就是告诉Redis命令只要集合中索引从0到2的元素,其他全部舍弃。这造就了一个非常简单但是有用的模式:LPUSH(RPUSH)+LTRIM(RTRIM)两个操作一起使用来添加新元素和删除超过一定限制的元素。

          注:LRANGE命令是一个时间复杂度为O(n)的命令,访问List的指向头部或者尾部的小范围元素的操作花费的时间是固定的。

          Blocking operations on lists

          Redis List有一个特别的功能,使他们可以实现排队,并且通常作为内部通信系统的一个阻塞块:阻塞操作。

          假想你要使用一个进程向List中添加元素,并且使用不同的进程对List中的添加的元素进行其他一些操作,这就是通常的生产者消费者模式,可以简单的通过下面方法来实现:

          • 向List中添加元素,生产者producer叫LPUSH命令。
          • 抓取和操作List中的元素,消费者consumer叫RPOP命令。

          但是,可能某些时候List是空的,没有可要操作的,RPOP命令仅仅返回NULL,这种情况下,消费者RPOP会被强制等待一些时间和再次重试,这也叫轮询并且关于这点并不是太好因为它有以下缺点:

          1.强制redis与客户端执行无用的命令(当List为空时,所有请求所执行的命令操作都是无用操作,仅仅返回NULL)。
          

          2.因为当返回Null时,等待一段时间会造成对元素操作进行的延迟,我们可以减少等待的时间,但是这样又回到了问题1。

            所以redis实现了RPOP和LPOP命令的升级版BRPOP和BLPOP命令,用于List为空时的的阻塞操作。这两个命令只有当有新元素添加到List中时或者是超过用户指定的超时时间时才返回给调用者。

            例如:

            >brpop tasks 5
            1)"tasks"
            2)"do_something"
            

              注:1)”tasks”:要操作的集合 2)”do_something”:集合中的可用元素,如果没有,则BRPOP命令一直阻塞到新元素添加或者超过5秒后返回。

              BRPOP命令要注意的事项:

              • 所有客户端按顺序的被服务。多个客户操作同一个List,那么某些客户端向List插入的元素总是被最先阻塞等待的客户端消费。

              • 此命令返回的值与RPOP不同,它返回的是包含List名称在内的两个元素的数组。主要是因为BRPOP和BLPOP可以同时针对于多个List进行阻塞操作。

              • 如果达到指定超时时间,那么将返回Null。

              Automatic creation and removal of keys

              到目前为止,前面所有例子都没有关于在向List添加元素前创建空的List,或者List中不在有元素时删除空集合的描述。因为Redis会自动在List为空时删除与在要添回到的List不存在时创建。

              当然不仅仅局限于List,此种机制适用于redis支持的所有由多元素组成的数据类型:Sets,Sorted sets和Hashes。

              此种机制总结:

              • 当我们将元素添加到聚合数据类型时,如果目标不存在,那么在插入之前将创建一个空的目标聚合数据类型对象。
              • 当从聚合数据类型删除元素时,如果值为空,对应的键会自动删除。
              • 在一个空的聚合对象类型上调用一些只读操作的命令如LLEN(返回List的长度)或者一些删除元素的写操作命令时,与目标对象持有命令操作的空的聚合类型一样总是产生相同的结果。
              文章知识点与官方知识档案匹配,可进一步学习相关知识
              算法技能树首页概览33847 人正在系统学习中

              与[转帖]redis list类型介绍相似的内容:

              [转帖]redis list类型介绍

              redis list类型介绍 要阐述redis的list数据类型,最好以一些理论开始,因为list术语在信息化众多技术中用的并不合适,如: 如Python中的list并不是链表结构,而是数组(同样的数据结构在Ruby语言中叫Array)。 以通常的观点来看,List仅仅是一个有序的元素序列:10,2

              [转帖]JMeter压测Redis

              https://www.cnblogs.com/yjlch1016/p/14052402.html 一、Redis Data Set插件: https://jmeter-plugins.org/wiki/RedisDataSet/ 该插件只能用于查询List和Set类型的数据,不能做增删改 下载的压

              [转帖]redis 获取 list 中的所有元素

              https://www.cnblogs.com/yaochanwangaun/p/14750318.html 一种方法是用 lrange( key, 0, -1 )。这种方法不会影响 redis list 中的数据。 $list = $redis->lrange( key, 0, -1 ); 另一种

              [转帖]Redis学习三(进阶功能).

              https://www.cnblogs.com/jmcui/p/11707970.html 阅读目录 一、排序 二、事务 三、流水线(pipeline) 四、发布订阅 回到顶部 一、排序 redis 支持对 list,set 和 zset 元素的排序,排序的时间复杂度是 O(N+M*log(M))。

              [转帖]Redis学习二(数据操作).

              阅读目录 key 操作 string 操作 list 操作 set 操作 zset 操作 hash 操作 HyperLogLog 操作 回到顶部 key 操作 删除 key:del key 批量删除key:redis-cli -a(密码)keys “QXJ_*”| xargs redis-cli -

              [转帖]redis中的bigkey问题

              https://cdn.modb.pro/db/459810 什么是bigkey bigkey就是redis key/value体系中的大value问题。我们知道redis的底层数据存储结构中,有多种数据结构的实现。 String: 简单动态字符串 List: 双向链表、压缩列表 Hash: 哈希表

              [转帖]Redis大key多key拆分方案

              https://www.cnblogs.com/-wenli/p/13612364.html 一、单个简单的key存储的value很大 二、hash, set,zset,list 中存储过多的元素 三、一个集群存储了上亿的key 四、大Bitmap或布隆过滤器(Bloom )拆分 背景 业务场景中经

              [转帖]redis集群报错CROSSSLOT Keys in request don‘t hash to the same slot

              先上结果: $redis->sDiffStore('live_room:robots:data:' . $info['id'], 'user_info:robots_list', ''); 上述代码执行后redis抛出一个异常。来看redis源码是如何抛出这个异常的(附redis源码地址:redis

              [转帖]Redis 7 参数 修改 说明

              2022-06-16 14:491800原创Redis 本文链接:https://www.cndba.cn/dave/article/108066 在之前的博客我们介绍了Redis 7 的安装和配置,如下: Linux 7.8 平台 Redis 7 安装并配置开机自启动 操作手册https://ww

              [转帖]Redis 7.0 三节点哨兵(Sentinel)高可用 环境搭建手册

              2022-06-17 16:253480原创Redis 本文链接:https://www.cndba.cn/dave/article/108088 1 哨兵高可用架构说明 Redis 最早的高可用方案是主从复制,但这种方案存在一个问题,就是当主库宕机后,从库不会自动切成主库,需要人工干预。 所有在主