• 简单介绍下Redis消息队列,实际生产环境中,大数据高并发时,不建议使用Redis做消息队列中间件


    十年河东,十年河西,莫欺少年穷

    学无止境,精益求精

    首先说下,我的 Redis 系列博客如下:

    [置顶] 高并发时,使用Redis应注意的问题【缓存穿透、缓存击穿.、缓存雪崩】

    windows环境下配置Redis主从复制-一主二仆,薪火相传、反客为主、哨兵模式

    Redis 持久化技术 ,大名鼎鼎的Rdb和Aof,你会选谁呢?

    简单介绍下Redis消息队列,实际生产环境中,大数据高并发时,不建议使用Redis做消息队列中间件

    Redis 事务,和传统的关系型数据库ACID并不同,别搞混了

    Redis常用配置redis.conf介绍,别把默认配置部署到到服务器,否则,会被领导骂的

    C# Nuget程序集StackExchange.Redis操作Redis 及 Redis 视频资源 及 相关入门指令 牛逼不,全都有

    Redis 的基础数据类型

    Window环境下安装Redis 并 自启动Redis 及 Redis Desktop Manager

    进入正文

    Redis消息队列的关键字

    Pub/Sub(发布/订阅)

    PSUBSCRIBE

    订阅一个或多个符合给定模式的频道。

    每个模式以 * 作为匹配符,比如 it* 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有以 news. 开头的频道( news.it 、 news.global.today 等等),诸如此类。

    PUBLISH

    将信息 message 发送到指定的频道 channel 。意思就是指:发布消息,订阅者可以接收

    PUBSUB

     是一个查看订阅与发布系统状态的内省命令, 它由数个不同格式的子命令组成, 以下将分别对这些子命令进行介绍。
    PUNSUBSCRIBE

    指示客户端退订所有给定模式。

    如果没有模式被指定,也即是,一个无参数的 PUNSUBSCRIBE 调用被执行,那么客户端使用 PSUBSCRIBE 命令订阅的所有模式都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的模式。

    SUBSCRIBE

    订阅给定的一个或多个频道的信息。
    UNSUBSCRIBE

    指示客户端退订给定的频道。

    如果没有频道被指定,也即是,一个无参数的 UNSUBSCRIBE 调用被执行,那么客户端使用 SUBSCRIBE 命令订阅的所有频道都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的频道。

    命令示例

    关注:

     SUBSCRIBE k1 k2 k3 k4 k5
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "k1"
    3) (integer) 1
    1) "subscribe"
    2) "k2"
    3) (integer) 2
    1) "subscribe"
    2) "k3"
    3) (integer) 3
    1) "subscribe"
    2) "k4"
    3) (integer) 4
    1) "subscribe"
    2) "k5"
    3) (integer) 5

    发布:

    C:Userschenwolong>redis-cli
    127.0.0.1:6379> ping
    PONG
    127.0.0.1:6379> PUBLISH k1 "hello My Name is k1"
    (integer) 1
    127.0.0.1:6379> PUBLISH k2 "hello My Name is k2"
    (integer) 1
    127.0.0.1:6379> PUBLISH k3 "hello My Name is k3"
    (integer) 1

    发布消息后,订阅者界面就可以看到发布的消息

     关于更多的指令演示,在此不做了,有兴趣的可以参考:Redis中文网

    最后贴出一个Redis实现消息队列的案例

    基于Redis实现消息队列典型方案

    1 概述
    2 基于List的 LPUSH+BRPOP 的实现
    3 PUB/SUB,订阅/发布模式
    4 基于SortedSet有序集合的实现
    5 基于 Stream 类型的实现
    6 其他实现

    1 概述

    消息队列,Message Queue,常用于解决并发系统中的资源一致性问题,提升峰值的处理能力,同时保证消息的顺序性、可恢复性、必送达性,对应用进行解耦,或者实现异步通讯等。市面上的 MQ应用有很多(例如:Kafka,RabbitMQ,Disque),同时也可以基于 Redis 来实现,比较典型的方案有:

    • 基于List的 LPUSH+BRPOP 的实现
    • PUB/SUB,订阅/发布模式
    • 基于Sorted-Set的实现
    • 基于Stream类型的实现

    在消息队列使用中,有生产者producter和消费者consumer。生产者负责生成消息,消费者负责使用处理消息。

    生产,指的是将消息放入消息队列。 消费,指的是读取并处理消息。通常一个消息再被消费后,就应该从消息队列中删除。

     

     

    接下来分别讨论具体实现方案。

    2 基于List的 LPUSH+BRPOP 的实现

    典型的命令为:

    LPUSH,将消息队列
    BRPOP,从队列中取出消息,阻塞模式

    就是一个典型的基于FIFL队列的解决方案。其中LPUSH是生产者做的事,而BRPOP是消费者做的事。

    该模式有很多优点:

    • 实现简单
    • Reids支持持久化消息,意味着消息不会丢失,可以重复查看(注意不是消费,只看不用,LRANGE类的指令)。
    • 可以保证顺序,保证使用LPUSH命令,可以保证消息的顺序性
    • 使用RPUSH,可以将消息放在队列的开头,达到优先消息的目的,可以实现简易的消息优先队列。

    同时也有些劣势:

    • 做消费确认ACK比较麻烦,就是不能保证消费者在读取之后,未处理后的宕机问题。导致消息意外丢失。通常需要自己维护一个Pending列表,保证消息的处理确认。
    • 不能做广播模式,例如典型的Pub/Discribe模式。
    • 不能重复消费,一旦消费就会被删除
    • 不支持分组消费,需要自己在业务逻辑层解决
    注意,没有好不好的技术,只有适合不适合。

    3 PUB/SUB,订阅/发布模式

    SUBSCRIBE,用于订阅信道
    PUBLISH,向信道发送消息
    UNSUBSCRIBE,取消订阅

    生产者和消费者通过相同的一个信道(Channel)进行交互。信道其实也就是队列。通常会有多个消费者。多个消费者订阅同一个信道,当生产者向信道发布消息时,该信道会立即将消息逐一发布给每个消费者。可见,该信道对于消费者是发散的信道,每个消费者都可以得到相同的消息。典型的对多的关系。

    典型的优点是:

    • 典型的广播模式,一个消息可以发布到多个消费者
    • 多信道订阅,消费者可以同时订阅多个信道,从而接收多类消息
    • 消息即时发送,消息不用等待消费者读取,消费者会自动接收到信道发布的消息

    也有些缺点:

    • 消息一旦发布,不能接收。换句话就是发布时若客户端不在线,则消息丢失,不能寻回
    • 不能保证每个消费者接收的时间是一致的
    • 若消费者客户端出现消息积压,到一定程度,会被强制断开,导致消息意外丢失。通常发生在消息的生产远大于消费速度时

    可见,Pub/Sub 模式不适合做消息存储,消息积压类的业务,而是擅长处理广播,即时通讯,即时反馈的业务。

    4 基于SortedSet有序集合的实现

    ZADD KEY score member,压入集合
    ZRANGEBYSCORE,依据score获取成员

    有序集合的方案是在自己确定消息顺ID时比较常用,使用集合成员的Score来作为消息ID,保证顺序,还可以保证消息ID的单调递增。通常可以使用时间戳+序号的方案。确保了消息ID的单调递增,利用SortedSet的依据Score排序的特征,就可以制作一个有序的消息队列了。

    和上面的方案相比,优点就是可以自定义消息ID,在消息ID有意义时,比较重要。缺点也明显,不允许重复消息(以为是集合),同时消息ID确定有错误会导致消息的顺序出错。

    所以,若不是需要自定义消息ID,这个方案好像有点鸡肋...

    5 基于 Stream 类型的实现

    这个Stream类型redis就是为了实现消息队列的。支持自动生成消息ID,分组消费,ACK,消息转移,队列监控等核心消息队列功能,请参考:基于Redis的Stream类型的完美消息队列解决方案,http://www.hellokang.net/redis/stream.html,来获取完整方案。

    6 其他实现

    很多成熟的MQ产品:

     @天才卧龙的博客

  • 相关阅读:
    Spring源码学习之容器的基本实现(一)
    面向对象设计原则
    简单易懂带你了解红黑树
    简单易懂带你了解二叉树
    单例模式
    原形模式
    数组与链表
    记一次解决postgresql数据库内存泄露的问题
    记一次排查CPU高的问题
    react ts 设置paths 和 声明非@types的模块
  • 原文地址:https://www.cnblogs.com/chenwolong/p/14562982.html
Copyright © 2020-2023  润新知