消息队列总结(3)- RabbitMQ & Kafka & RocketMQ高可用方案

目录

[1. 什么是高可用?](#1. 什么是高可用?)

[1.1 常见的高可用方法](#1.1 常见的高可用方法)

[1.2 消息队列的高可用](#1.2 消息队列的高可用)

[2. RabbitMQ的高可用方案](#2. RabbitMQ的高可用方案)

[2.1 镜像队列](#2.1 镜像队列)

[2.2 消息生产的确认机制](#2.2 消息生产的确认机制)

[2.3 消息的持久化](#2.3 消息的持久化)

[3. Kafka的高可用方案](#3. Kafka的高可用方案)

[3.1 消息备份](#3.1 消息备份)

[3.2 ISR & IEO & HW](#3.2 ISR & IEO & HW)

[3.3 消息生产的确认机制](#3.3 消息生产的确认机制)

[4. RocketMQ的高可用方案](#4. RocketMQ的高可用方案)

[4.1 消息备份机制](#4.1 消息备份机制)

[5.RabbitMQ & Kafka & RocketMQ差异总结](#5.RabbitMQ & Kafka & RocketMQ差异总结)

[6. 参考资料](#6. 参考资料)


1. 什么是高可用?

1.1 常见的高可用方法

高可用(High Availability,简称HA)是指一个系统、应用程序或服务可以在发生故障或其他异常情况时,仍然能够保持可用性和稳定性,确保用户能够无缝访问和使用。

我们通常实现高可用的方法包括:

  • 数据备份:为了保障数据的可靠性和可用性,在数据存储设备中,存储多个副本。在极端情况下一个存储设备故障时,可以使用其他副本进行数据恢复。
  • 服务冗余:常见的服务冗余方法包括:主备模型(1个活动主节点对应多个从节点)、双主模型(2个活动主节点,且两个节点互备)、N+1(包含N个活动主节点+1个备用节点)。此外服务冗余还需要配合负载均衡策略,避免单个服务过载或崩溃。
  • 容错设计:是指编写健壮的代码,容错设计中需要考虑的包括:异常处理、重试机制、幂等设计等。常见的做法是在服务端接口设计时,需要使用乐观锁、唯一标识等手段保障幂等。在客户端可以及时抛出异常让业务人员重试,或者捕获异常进行多次重试。
  • 故障检测:是指通过冗余侦测线,经过复杂的监听程序,逻辑判断,来判断是否故障。常见的方法包括:集群各节点之间的心跳检测、集群各节点与仲裁设备之间的心跳检测。
  • 故障转移(FailOver):是指检测到服务故障的前提下,通过调整负载均衡策略,避免流量路由到故障服务的方法。这里对于那些已经在执行中的请求可能会产生影响,需要配合客户端重试把影响降到最低。
  • 故障回转(FailBack):在故障恢复后,我们通常需要调整负载均衡策略,把流量重新路由到原服务。这里需要注意,若服务涉及到数据存储,需要追上丢失的数据,再切回流量。

1.2 消息队列的高可用

这里说的消息队列的高可用特指消息队列集群所做的高可用设计,无论是RabbitMQ、Kafka,还是RocketMQ,在高可用上都做到了数据备份、服务冗余,他们的核心差异在于不同的消息队列++数据备份的力度、消息同步机制、消息持久化机制++的设计思想上存在差异。

2. RabbitMQ的高可用方案

2.1 镜像队列

消息生产:如果生产者与Slave建立连接,Slave会把请求转发到Master,Master存储后再把请求转发到其他Slave进行存储。

消息消费:如果消费者与Slave建立连接并进行订阅消费,实质上请求会被转发到Master上获取信息,只不过看似是从Slave上消费而己。这里的疑问是,这里的Master会不会压力比较大?答案是如果我们的各个队列的Leader能够平均分布在各个Broker,就不会给一个Broker带来特别大的压力。

Slave升级:当Master挂掉之后,会触发把消息队列最长的升级为Master。

此外,为了避免机房断电、断网等极端情况,RabbitMQ还提供了Shovel远程模式,把消息存储在跨地域的两个不同的数据中心,并让两个跨地域的两个MQ集群互联

2.2 消息生产的确认机制

镜像队列只是解决了一个节点宕机后,还有其他备用节点可用。但是RabbitMQ针对主从复制的机制是什么样的?是否能保障切换时主从节点的一致性呢?

在早期的RabbitMQ,主从复制的方案是++异步复制++,也就是当消息被存储到到Master节点后,会立刻给生产者进行ACK,表示消息已经被接收并写入成功,此时,Slave节点可能还没有完全同步数据。

但是,从 RabbitMQ 3.7 版本开始,RabbitMQ 增加了一个新的队列类型 quorum queue(法定队列),通过提供一种基于 Paxos 的一致性算法来保证数据在主从节点之间的强一致性。

2.3 消息的持久化

  • 什么时间需要持久化:1.队列本身就被配置为持久化时(队列的durable属性设置为true);2.针对非持久化队列,内存紧张时需要将部分内存中的消息转存到磁盘(内存换页)。
  • 什么时间触发持久化:1.写入磁盘之前会有Buffer,默认大小为1M,若Buffer已满则触发写入磁盘;2.无论Buffer满不满,有一个固定的刷盘实践(25ms);

3. Kafka的高可用方案

3.1 消息备份

Kafka允许一个队列存在多个Partition,每个Partition存在一个Leader和多个Follower。生产者将消息直接发往对应Partition的Leader,Follower会周期地向Leader发送同步请求,Kafka的Leader机制在保障数据一致性地同时降低了消息备份的复杂度。

3.2 ISR & IEO & HW

  • ISR(In-Sync Replicas):指的是一个Partition中与Leader"保持同步"的Replica列表(实际存储的是副本所在Broker的BrokerId),这里的保持同步不是指与Leader数据保持完全一致,只需在replica.lag.time.max.ms时间内与Leader保持有效连接。

  • LEO(log end offset):即日志末端偏移,指向了副本日志中下一条消息的位移值(即下一条消息的写入位置)。

  • HW(high watermark):即已同步消息标识,因其类似于木桶效应中短板决定水位高度,故取名高水位线。

下图详细的说明了当Producer生产消息至Broker后,ISR以及HW和LEO的流转过程:

3.3 消息生产的确认机制

  • acks=0

生产者无需等待服务端的任何确认,消息被添加到生产者套接字缓冲区后就视为已发送,因此acks=0不能保证服务端已收到消息,使用场景较少。

  • acks=1

Leader将消息写入本地日志后无需等待Follower的消息确认就做出应答。如果Leader在应答消息后立即宕机且其他Follower均未完成消息的复制,则该条消息将丢失。

  • acks=all

Leader将等待ISR中的所有副本确认后再做出应答,因此只要ISR中任何一个副本还存活着,这条应答过的消息就不会丢失。acks=all是可用性最高的选择,但等待Follower应答引入了额外的响应时间。Leader需要等待ISR中所有副本做出应答,此时响应时间取决于ISR中最慢的那台机器。

4. RocketMQ的高可用方案

4.1 消息备份机制

为了保障RocketMQ不丢消息,RocketMQ一般是将Broker部署成Master-Slave模式。其中Master节点负责处理消息的写入和读取请求,Slave节点则进行数据的复制以及读取请求的负载均衡。通常RocketMQ的主从复制方案包括:

  • 同步复制:当Master节点接受到消息后,执行两个动作:消息持久化、发起主从同步。Master节点等待所有Slave节点都将该消息同步完成之后再返回执行结果。这样可以保证数据的一致性,但会对性能造成一定影响,因为需要等待所有的Slave节点都同步完成之后才能继续处理数据。
  • 异步复制(默认方案):异步复制使用一个后台不断运行的线程,主要包括两部分Slave节点向Master节点反馈主从复制进度、Master节点主动向Slave节点同步消息。

5.RabbitMQ & Kafka & RocketMQ差异总结

  • 消息备份机制:RabbitMQ是通过镜像队列实现高可用,Kafka是通过分区副本机制来实现高可用,RocketMQ是通过主从节点的复制来实现高可用。
  • 消息确认机制:RabbitMQ消息在Master节点写入之后,就可以给Producer进行ACK;Kafka提供了ACK=0(无需写入即ACK)、ACK=1(Leader节点写入后ACK)、ACK=all(所有节点写入后ACK)三种模式;RocketMQ支持同步复制(所有节点吸入后ACK)、异步复制(Master节点写入后ACK)两种模式
  • 消费者ACK处理机制:如果消息还未被ACK,此时Broker发生宕机,RabbitMQ、Kafka、RocketMQ的处理机制比较类似,都是通过重试把消息发送到新的消费者来消费。

6. 参考资料

镜像队列 - RabbitMQ 教程

基于MySql,Redis,Mq,ES的高可用方案解析

Kafka架构、高性能和高可用性分析_aijiudu的博客-CSDN博客

Kafka的存储机制和可靠性_kafka作为数据缓存区_Lion Long的博客-CSDN博客

解开Kafka神秘的面纱(二):Kafka的高效读写与消息安全_kafaka_毛奇志的博客-CSDN博客

RocketMQ保证高可用和高性能的几种措施

RocketMQ原理:RocketMQ高可用原理 - 墨天轮

我理解的RocketMQ:主从复制HA(high availability)的机制分析_rocketmq的ha机制_xiaojkql的博客-CSDN博客

高可用集群_高可用集群实现高可用性的方法主要有_尐譽的博客-CSDN博客

实现高可用的 11 个关键技巧_如何实现高可用_a1405的博客-CSDN博客

高可用架构设计的六个方法_梯度科技的博客-CSDN博客

服务容错设计:流量控制、服务熔断、服务降级_张维鹏的博客-CSDN博客

可靠性设计:容错设计_软件容错_徐步陌上行的博客-CSDN博客

RabbitMQ的高可用方案_rabbitmq高可用方案_倔强100%的博客-CSDN博客

RabbitMQ的高可用、高可靠保证_rabbitmq高可用_柠檬丶Ewing的博客-CSDN博客

RabbitMQ持久化机制_琦彦的博客-CSDN博客

RabbitMQ VS Apache Kafka (九)------ RabbitMQ集群的分区容错性与高可用性-腾讯云开发者社区-腾讯云

相关推荐
xmyLydia3 小时前
Kafka 本地开发环境 + 可视化 UI 快速搭建与排坑记录
kafka
杭州杭州杭州17 小时前
ubuntu 18.04安装tomcat,zookeeper,kafka,hadoop,MySQL,maxwell
hadoop·mysql·ubuntu·zookeeper·kafka·tomcat
精神内耗中的钙奶饼干20 小时前
Springboot整合kafka记录
后端·kafka
noravinsc1 天前
python 使用rabbitmq
python·rabbitmq·ruby
烛.照1031 天前
RabbitMQ消息的可靠性
linux·docker·rabbitmq
smileNicky1 天前
RabbitMQ架构原理及消息分发机制
分布式·架构·rabbitmq
noravinsc1 天前
windows上rabbitmq服务激活后 15672无法打开
windows·分布式·rabbitmq
努力的搬砖人.1 天前
Spring Boot整合Kafka的详细步骤
spring boot·后端·kafka
AUGENSTERN_dc2 天前
RaabitMQ 快速入门
java·后端·rabbitmq
Charlie__ZS2 天前
RabbitMQ
分布式·rabbitmq