消息队列是如何保证高可用的

消息队列是如何保证高可用的?redis

可靠性保证

已RocketMQ为例:数据库

  • 集群为多master模式
  • 多master多slave异步复制模式
  • 多master多slave同步复制模式

NameServer相似于kafka的zk,起到master和slave的注册和发现。 Producer和NameServer集群的随机一点创建长连接,按期从NameServer获取Topic路由信息,并向Topic服务的Broker Master创建长连接,且定时向Broker发送心跳。网络

Producer发送消息到Broker master,Consumer能够从Topic的Master和Slave的broker订阅消息。架构

对比看下kafka的架构图: 异步

经过zk管理集群配置,选举leader及对consumer group进行rebalance。 consumer能够采用pull和push方式订阅消息。blog

RabbitMq能够经过普通集群和镜像模式进行可用性保证。队列

消息重复消费

不一样的MQ有不一样的消费机制,ack以后消息会从消息队列中删除。 形成重复消费的缘由可能有如下几点:事务

  • 网络传输故障
  • 消息确认没有返回队列服务端

业务上的解决:路由

  • 若是数据库消费,能够创建惟一约束,避免脏数据
  • 引入redis作幂等查询

消息的可靠性传输

可靠性从如下几个调度考虑:kafka

  • 生产者丢数据
  • 消息队列丢数据
  • 消费者丢数据

RabbitMq的transaction机制,在发送消息以前,开启事务,而后发送消息,若是出现异常进行回滚,发送成功执行commit。

信道发出去的消息会被指派一个惟一ID,消息路由到队列后,队列会返回Ack信息其中包含惟一ID,打到确认目的,若是没能处理此消息,会返回NAck,以后进行重试操做。

队列为防止丢数据,通常开启磁盘持久化,能够在confirm持久化磁盘后返回ack,这样保证了消息的持久化。

  • queue设置为durable为true,表示持久化队列
  • 发送消息时将deliveryMode = 2

消费者能够采用自动确认模式,确认后当即删除,为解决丢失数据后,重复消费,能够关闭自动确认,采用手动确认。

producer发送消息到partition后,经过zk找到partition的leader,leader写入本地log,follower主动从leader来pull数据。

能够配置produder的acks=all,这样须要follower同步后才确认消息发送成功。 producer设置retries=MAX,写入失败后会进入无限重试。

为保证zk切换leader过程当中数据丢失,能够配置replication.factor,即设置副本数量,要求每一个partition必须至少2个副本。min.insync.replicas,是leader须要感知至少多少个follower和本身保持联系。

kafka消费主要依赖于offset,每一个消费组消费的消息都有惟一的offset下标,消费者消费后提交offset。

消息顺序性

业务上通常没有这类需求,通常能够采用将消息放到一个信道里面,kafka的partiton,rabbitMq的queue,而后控制消费者顺序消费。

相关文章
相关标签/搜索