消息队列总结(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集群的分区容错性与高可用性-腾讯云开发者社区-腾讯云

相关推荐
我一直在流浪29 分钟前
Kafka - 消费者程序仅消费一半分区消息的问题
分布式·kafka
B站计算机毕业设计超人3 小时前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
Mephisto.java7 小时前
【大数据学习 | Spark】Spark的改变分区的算子
大数据·elasticsearch·oracle·spark·kafka·memcache
KevinAha14 小时前
Kafka 3.5 源码导读
kafka
求积分不加C14 小时前
-bash: ./kafka-topics.sh: No such file or directory--解决方案
分布式·kafka
nathan052914 小时前
javaer快速上手kafka
分布式·kafka
懒洋洋大魔王15 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
激流丶17 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
天冬忘忧1 天前
Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化
大数据·分布式·kafka
工业甲酰苯胺1 天前
Python脚本消费多个Kafka topic
开发语言·python·kafka