目录
1. 什么是高可用?
1.1 常见的高可用方法
1.2 消息队列的高可用
2. RabbitMQ的高可用方案
2.1 镜像队列
2.2 消息生产的确认机制
2.3 消息的持久化
3. Kafka的高可用方案
3.1 消息备份
3.2 ISR & IEO & HW
3.3 消息生产的确认机制
4. RocketMQ的高可用方案
4.1 消息备份机制
5.RabbitMQ & Kafka & RocketMQ差异总结
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集群的分区容错性与高可用性-腾讯云开发者社区-腾讯云