• 【Redis】List类型


    目录

    List列表

    命令

    LPUSH

    LPUSHX

    RPUSH 

    RPUSHX

    LRANGE

    LPOP

    RPOP

    LINDEX

    LINSERT

    LLEN

    lrem

    ltrim

    lset

    阻塞版本命令

    BLPOP

    BRPOP 

    内部编码

    使用场景

    消息队列

    分频道的消息队列

    作为栈或者队列


    List列表

    列表类型是⽤来存储多个有序的字符串,如图下图所示a、b、c、d、e 五个元素从左到右组成了⼀个有序的列表,列表中的每个字符串称为元素(element),⼀个列表最多可以存储2^{32}-1个元素。在 Redis 中,可以对列表两端插⼊(push)和弹出(pop),还可以获取指定范围的元列表、获取指定索引下标的元素等。列表是⼀种⽐较灵活的数据结构,它可以充当栈和队列的⻆⾊,在实际开发上有很多应⽤场景。

    列表类型的特点:

    • 列表中的元素是有序的,这意味着可以通过索引下标获取某个元素或者某个范围的元素列表
    • 区分获取和删除的区别
    • 列表中的元素是允许重复的


    命令

    LPUSH

    将一个或者多个元素从左侧放入(头插)到list中。 

    语法:

     LPUSH key element [element ...]

    时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

    返回值:插⼊后 list 的⻓度。

    ⽰例:

    LPUSHX

    在 key 存在时,将⼀个或者多个元素从左侧放⼊(头插)到 list 中。不存在,直接返回

    语法:

    LPUSHX key element [element ...]

    时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

    返回值:插⼊后 list 的⻓度。

    ⽰例:

    RPUSH 

    将⼀个或者多个元素从右侧放⼊(尾插)到 list 中。

    语法:

    RPUSH key element [element ...]

    时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

    返回值:插⼊后 list 的⻓度。

    ⽰例:

    RPUSHX

    在 key 存在时,将⼀个或者多个元素从右侧放⼊(尾插)到 list 中。

    语法:

    RPUSHX key element [element ...]

    时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

    返回值:插⼊后 list 的⻓度。

    ⽰例:

    LRANGE

    获取从 start 到 end 区间的所有元素,左闭右闭。

    语法:

    LRANGE key start stop

    时间复杂度:O(N)

    返回值:指定区间的元素。

    ⽰例:

    说明:

    • 在C++中,下标超出范围,一般认为这是一个”未定义行为“;可能会导致程序崩溃,也可能会得到一个不合法的数据,还可能会得到一个看起来合法但是是错误的数据,也有可能恰好的到一个符合要求的数据;缺点:程序员不一定在第一时间发现问题;优点:效率非常高
    • 在Java中,下标超出范围,一般会抛出异常,多出一步合法下标的验证 缺点:效率或者速度相比C++比较慢 优点:出现问题能够及时发现
    • 在Redis中并没有采用上述两种设定,Redis的做法是直接尽可能的获取到给定区间的元素,如果区间非法,比如超出下标就会尽可能的获取对应的内容

    LPOP

    从 list 左侧取出元素(即头删)。

    语法:

    LPOP key

    时间复杂度:O(1)

    返回值:取出的元素或者 nil。

    ⽰例:

    RPOP

    从 list 右侧取出元素(即尾删)。

    语法:

    RPOP key

    时间复杂度:O(1)

    返回值:取出的元素或者 nil。

    ⽰例:

    LINDEX

    获取从左数第 index 位置的元素。

    语法:

    LINDEX key index

    时间复杂度:O(N)

    返回值:取出的元素或者 nil。

    ⽰例:

    说明:并没有RINDEX命令,如果我们想从左边开始获取元素,可以让index设置为负数; 

    LINSERT

    在特定位置插⼊元素。

    语法:

    LINSERT key <BEFORE | AFTER> pivot element

    时间复杂度:O(N)

    返回值:插⼊后的 list ⻓度。

    ⽰例: 

    LLEN

    获取 list ⻓度。

    语法:

    LLEN key

    时间复杂度:O(1)

    返回值:list 的⻓度。

    ⽰例:

    lrem

    删除指定个数的指定元素

    语法:

    LERM key count element

    时间复杂度:O(K)

    返回值:删除元素的个数

    示例:

    说明:

    • 当count>0时,从list的左边开始删除
    • 当count<0时,从list的右边开始删除
    • 当count=0时,删除 list中的所有元素 

    ltrim

    保留start和stop之间区间的内的元素(区间外面两边的元素就直接被删除了)

    语法:

    LTRIM key start stop

    时间复杂度:O(K)

    返回值:执行成功返回OK

    示例:

    lset

    根据下标修改元素

    语法:

    LSET key index element

    时间复杂度:O(N)

    返回值:执行成功返回OK

    示例:


    阻塞版本命令

    blpop 和 brpop 是 lpop 和 rpop 的阻塞版本,和对应⾮阻塞版本的作⽤基本⼀致,除了:

    • 在列表中有元素的情况下,阻塞和⾮阻塞表现是⼀致的。但如果列表中没有元素,⾮阻塞版本会理解返回 nil,但阻塞版本会根据 timeout,阻塞⼀段时间,期间 Redis 可以执⾏其他命令,但要求执⾏该命令的客⼾端会表现为阻塞状态。
    • 命令中如果设置了多个键,那么会从左向右进⾏遍历键,⼀旦有⼀个键对应的列表中可以弹出元素,命令⽴即返回。
    • 如果多个客⼾端同时多⼀个键执⾏ pop,则最先执⾏命令的客⼾端会得到弹出的元素。

    BLPOP

    LPOP的阻塞版本

    语法:

     BLPOP key [key ...] timeout

    时间复杂度:O(1)

    返回值:取出的元素或者 nil。

    示例:

    BRPOP 

    RPOP的阻塞版本

    语法:

     BRPOP key [key ...] timeout

    时间复杂度:O(1)

    返回值:取出的元素或者 nil。

    示例:和上面BLPOP的用法相似就不演示了


    内部编码

    在Redis 5版本中,List的内部编码主要是quicklist。quicklist是Redis 3.2版本引入的一种新的数据结构,它是ziplist和linkedlist的结合体,旨在更好地平衡内存使用和访问速度。

    quicklist通过维护一个双向链表,链表的每个节点都是一个ziplist。这种设计使得quicklist既能够像ziplist一样节省内存(因为ziplist会将多个元素压缩存储在一起),又能够像linkedlist一样快速地在两端进行插入和删除操作(因为linkedlist的双向特性)。


    使用场景

    消息队列

    如下图所⽰,Redis 可以使⽤ lpush + brpop 命令组合实现经典的阻塞式⽣产者-消费者模型队列,⽣产者客⼾端使⽤ lpush 从列表左侧插⼊元素,多个消费者客⼾端使⽤ brpop 命令阻塞式地从队列中"争抢" 队⾸元素。通过多个客⼾端来保证消费的负载均衡和⾼可⽤性。

    Redis阻塞消息队列模型

    分频道的消息队列
     

    如下图所⽰,Redis 同样使⽤ lpush + brpop 命令,但通过不同的键模拟频道的概念,不同的消费者可以通过 brpop 不同的键值,实现订阅不同频道的理念。

    Redis分频道阻塞消息队列模型

    作为栈或者队列

    选择列表类型时,请参考:

    同侧存取(lpush + lpop 或者 rpush + rpop)为栈

    异侧存取(lpush + rpop 或者 rpush + lpop)为队列


    今天对Resid中list列表类型的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法;个人主页还有很多精彩的内容。您三连的支持就是我前进的动力,感谢大家的支持!!! 

  • 相关阅读:
    grav安装教程
    Docker /var/lib/docker数据目录迁移
    Nmap爆破MySQL弱口令漏洞:解决报错Accounts: No valid accounts found
    基于信息检索和深度学习结合的单元测试用例断言自动生成
    kudeadm 部署 k8s
    MTK外部按键新增
    virtual box 导入vdi虚拟系统文件.
    一款好用的leetcode周赛插件:再也不用写代码的时候来回看描述了
    1334. 阈值距离内邻居最少的城市
    单稳态中间继电器UEG/A-4DPDT/DC220V
  • 原文地址:https://blog.csdn.net/qq_55119554/article/details/141056765