Redis_发布订阅(基础)

目录

  前言

  生产者和消费者

  发布和订阅

  注意

前言

  随着业务复杂, 业务的项目依赖关系增强, 使用消息队列帮助系统降低耦合度.发布订阅(pub/sub)是一种消息通信模式,主要目的是解除消息发布者、消息订阅者之间的耦合
  订阅分布本身也是一种生产者消费者模式, 订阅者是消费者, 发布者是生产者.
  订阅发布模式, 发布者发布消息后, 只要有订阅方, 则多个订阅方会收到同样的消息
  生产者消费者模式, 生产者往队列里放入消息, 由多个消费者对一条消息进行抢占.
  订阅分布模式可以将一些不着急完成的工作放到其他进程或者线程中进行离线处理.

pub/sub的特点

(1)时间非耦合
  发布者和订阅者不必同时在线,它们不必同时参与交互
(2)空间非耦合
  发布者和订阅者不必相互知道对方所在的位置
(3)同步非耦合
  发布者/订阅者是异步模式,发布者可不断地生产消息,订阅者则可异步地得到消息通知
pub/sub的使用场景
    基于pub/sub的特点,他的典型使用场景就是实时消息系统,比如即时聊天,群聊等功能,还常用作减轻高并发的I/O写压力,例如大量的写日志操作,如果实时写入日志文件或者数据库,会造成I/O超负荷,降低系统性能,那么就可以用pub/sub方式,写日志时先不进行写操作,而是向日志频道发布一条日志消息,然后有一个单独的日志程序来订阅日志频道,异步的读取日志消息写入文件或数据库

Redis中的订阅发布模式, 当没有订阅者时, 消息会被直接丢弃(Redis不会持久化保存消息)

生产者和消费者

  生产者使用Redis中的list数据结构进行实现, 将待处理的消息塞入到消息队列中.

具体内容放在下次“消息通道异步处理”讲

发布和订阅

在Redis Pubsub中, 一个频道(channel)相当于一个消息队列,

“发布/订阅”模式包含两种角色,分别是发布者和订阅者。订阅者可以订阅一个或若干个频道(channel),而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到此消息。

发布者发送消息的命令是PUBLISH,用法是PUBLISH channel message,如向channel.1说一声“hi”:
redis>PUBLISH channel.1 hi
(integer) 0
这样消息就发出去了。返回值表示接收到这条消息的订阅者数量。发出去的消息不会被持久化,也就是说当客户端订阅channel.1后只能收到后续发布到该频道的消息,之前发送到就收不到了。

订阅频道的命令是SUBSCRIBE,可以同时订阅多个频道,用法是 SUBSCRIBE channel [channel ...]。
redis>SUBSCRIBE channel.1
  Reading messages... (press Ctrl-C to quit)
  1) "subscribe"
  2) "channel.1"
  3) (integer) 1
执行SUBSCRIBE命令后进入订阅状态,处于此状态下客户端不能使用除SUBSCRIBE/UNSUBSCRIBE/PSUBSCRIBE/PUNSUBSCRIBE这四个属于“发布/订阅”模式之外的命令,否则会报错。
进入订阅模式后客户端可能收到三种类型的回复。每种类型的回复都包含3个值,第一个值是消息的类型,根据消息类型的不同,第二第三个值的含义也不同。消息类型可能的取值有:
  1)Subscribe。表示订阅成功的反馈信息。第二个值是订阅成功的频道名称,第三个值是当前客户端订阅的频道数。
  2)message。这个类型的回复表示收到的消息。第二个值表示产生消息的频道名称,第三个值是消息内容。
  3)unsubscribe。表示成功取消订阅某个频道。第二个值是对应的频道名称,第三个值是当前客户端订阅的频道数量,当此值为0时客户端会退出订阅状态。

redis 将所有频道的订阅关系都保存在 pubsub_channels 字典里面,这个字典的键是某个被订阅的频道,而键的值则是一个链表,链表里面记录了所有订阅这个频道的客户端。当某频道有新消息时,就会查找对应的链表,向链表中每个客户端发送通知

当一个连接通过subscribe或者psubscribe订阅通道后就进入订阅模式。在这种模式除了再订阅额外的通道或者用unsubscribe或者punsubscribe命令退出订阅模式,就不能再发送其他命令。另外使用 psubscribe命令订阅多个通配符通道,如果一个消息匹配上了多个通道模式的话,会多次收到同一个消息。

注意 

  1.在Jedis中订阅方处理是采用异步的方式,
    如同步的方式,在do-while循环中, 会等到当前消息处理完毕才能够处理下一条消息, 这样会导致当入队列消息量过大的时候, redis链接被强制关闭.

  2.“单点问题”,如果发布者的消息过多,一台redis-server处理不过来,redis还没支持负载均衡集群,主从配置在“消息过多”情况下还是无能为力,接收消息的压力始终都得在主的压力上面。这种情况下只能人为的将发布者的消息按照业务拆分,将某些消息发布到另外一台redis server上面去。
  3.通过负载均衡集群来增加自己的接收消息的能力,通过主从配置解决 redis-server的消息分发能力不够。
  4.如果redis-server的订阅端处理能力不足怎么办?这一点对于redis sever非常危险。因为redis-server会将消息存储在redis server 服务端内存中,如果订阅端的处理始终处理缓慢,那么redis server的内存就会不断变大。

时间: 2024-10-07 19:52:24

Redis_发布订阅(基础)的相关文章

Redis_发布订阅(Spring Boot)

目录 前言 生产者和消费者 发布和订阅 Java实现 注意 转至 http://www.tianmaying.com/tutorial/springboot-redis-message 前言 利用Spring Data对Redis的支持来实现消息的发布订阅机制.使用StringRedisTemplate来发布一个字符串消息,同时基于MessageListenerAdapter使用一个POJO来订阅和响应该消息.Receiver类将会被注册为一个消息监听者时.给Receiver的构造函数通过@Au

MQTT的学习研究(十四) MQTT moquette 的 Callback API 消息发布订阅的实现

在moquette-mqtt中提供了回调callback模式的发布和订阅但是在订阅之后没有发现有消息接收的方法,参看moquette-mqtt中Block,Future式的发布订阅基础是callback式订阅发布,但是本人在研究源代码测试,发现 callback方式接收没有成功.所以本文中只是callback式的发布和订阅没有消息接收的过程,尚未查到原因. 采用Callback式 发布主题 Java代码   package com.etrip.mqtt.callback; import java

RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用

本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Redis发布订阅—Pub/Sub模式或者说是观察者模式.我想大家即使没有使用过,也已经耳熟能详了. 先简单举例说明下应用场景,在场景中我们可以分析到其优势在哪. 比如你的线上应用应用,你想设置一个日志报警系统,当应用出现异常的时候,立马发送通知给你,可能是短信的形式,也可能是邮件的形式.当然如果只将报

分布式发布订阅消息系统 Kafka 架构设计[转]

分布式发布订阅消息系统 Kafka 架构设计 转自:http://www.oschina.net/translate/kafka-design 我们为什么要搭建该系统 Kafka是一个消息系统,原本开发自LinkedIn,用作LinkedIn的活动流(activity stream)和运营数据处理管道(pipeline)的基础.现在它已为多家不同类型的公司 作为多种类型的数据管道(data pipeline)和消息系统使用. 活动流数据是所有站点在对其网站使用情况做报表时要用到的数据中最常规的部

分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.NET Socket Tcp 技术实现的分布消息总线,也是一个简单的发布订阅框架: 并且以案例的形式为大家演示了如何使用这个分布式消息总线架构发布订阅架构模式的应用程序,在得到各位同仁的反馈的同时,大家也非常想了解订阅者离线的情况,即支持离线构发布订阅框架. 二.离线架构 不同于订阅者.发布者都同时在

Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)

前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还是有一定距离, 本系列将对Thrift作代码解读和框架扩充, 使得它更加贴近生产环境. 本文讲述如何借用zookeeper来实现中介角色, 使得服务端和客户端解耦, 并让RPC服务平台化发展. 基础架构: RPC服务往平台化的方向发展, 会屏蔽掉更多的服务细节(服务的IP地址集群, 集群的扩容和迁移

javascript 设计模式 -- 发布/订阅模式

直接上代码: index.html : <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>设计模式</title> </head> <body> <div id="box"> <div>{{message}}</div> <

RabbitMQ 发布订阅持久化

RabbitMQ是一种重要的消息队列中间件,在生产环境中,稳定是第一考虑.RabbitMQ厂家也深知开发者的声音,稳定.可靠是第一考虑,为了消息传输的可靠性传输,RabbitMQ提供了多种途径的消息持久化保证:Exchange持久化.Queue持久化及Message的持久化.以保证RabbitMQ在退出或Crash等异常情况下,消息不会丢失.RabbitMQ提供了简单的参数配置来实现持久化操作. 简单说明一下各种持久化方式:(描述代码采用的是Rabbit.Client  SDK,  C#代码)

异步编程解决方案之事件发布/订阅模式

时间监听模式是广泛用于异步编程的模式,是回调函数的事件化,又称不发订阅模式. nodejs的events模块就是发布订阅模式的一个简单实现,不存在preventDefault,stopPropagation,stopImmediatePropagation,等控制事件传递的方法. 它具有addListner/on(),once(),removeListner(),removeAllLisetner()和emit等基础监听事件方法. 事件发布/订阅十分简单,如下: //订阅 emitter.on(