Kafka 与RocketMQ 可靠性比较

本文通过模拟Broker进程被Kill及物理机掉电的场景,对比了Kafka与RocketMQ的消息丢失情况,发现二者在进程退出时都能较好地保证消息不丢失,但在机器掉电时,通过调整刷盘策略,RocketMQ能在保证消息不丢失的同时维持较高吞吐量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kafka vs RocketMQ——单机系统可靠性


引言

前几期的评测中,我们对比了Kafka和RocketMQ的吞吐量和稳定性,本期我们要引入一个新的评测标准——软件可靠性。

  • 何为“可靠性”

先看下面这种情况:有A,B两辆越野汽车,在城市的周边地区均能很好应对泥泞的路况。当一同开去穿越西藏,A车会因为西藏本地的汽油不达标,导致油路受阻无法点火,而B车顺利完成了穿越。因此我们说,B车的可靠性比A车高。

  • 何为“软件可靠性”

“软件的可靠性”就是考察软件在各种异常突发的情况下的应对能力。常见的软件异常有:磁盘损坏、进程意外退出、宿主机宕机等情况。

  • 何为“消息中间件的可靠性”

对于消息中间件来说,“可靠性”最直接的指标就是——消息数据不丢失。此外,消息不重投、服务一主多备等特性也可以用来评估可靠性。

那么Kafka和RocketMQ(以下简称RMQ)在可靠性上孰优孰劣呢?和我们走进本期的测试比拼吧!

测试目的

在消息收发的过程中,分别模拟Broker服务进程被Kill、物理机器掉电的异常场景,多次实验,查看极端情况下消息系统的可靠性。

测试场景

以下场景使用多个发送端向一个Topic发送消息,发送方式为同步发送,分区数为8,只启动一个订阅者。

场景1. 模拟进程退出

在消息收发过程中,利用Kill -9 命令使Broker进程终止,然后重新启动,得到可靠性数据如下:

注:以上测试场景中Kafka的异步刷盘间隔为1秒钟,同步发送需设置request.required.acks=1,否则会出现消息丢失。

在Broker进程被终止重启,Kafka和RMQ都能保证同步发送的消息不丢,因为进程退出后操作系统能确保将该进程遗留在内存的数据刷到磁盘上。实验中,Kafka出现了极少量的消息重复。再次可以确定此场景中,二者的可靠性都很高。

场景2. 模拟机器掉电

在消息收发过程中,直接拔掉Broker所在的宿主机电源,然后重启宿主机和Broker应用。因受到机房断电限制,我们在本场景测试中使用的是普通PC机器。得到可靠性数据如下:

测试发现,即使在并发很低的情况下,Kafka和RMQ都无法保证掉电后不丢消息。这个时候,就需要改变刷盘策略了。我们把刷盘策略由“异步刷盘”变更为“同步刷盘”,就是说,让每一条消息都完成存储后才返回,以保证消息不丢失。
注:关于两种刷盘模式的详细区别可以参照文档最下方的说明

重新执行上面的测试,得到数据如下:

首先,设置同步刷盘时,二者都没出现消息丢失的情况。限于我们使用的是普通PC机器,两者吞吐量都不高。此时Kafka的最高TPS仅有500条/秒,RMQ可以达到4000条/秒,已经是Kafka的8倍。

为什么Kafka的吞吐量如此低呢?因为Kafka本身是没有实现任何同步刷盘机制的,就是说在这种场景下测试,Kafka注定是要丢消息的。但要想做到每一条消息都在落盘后才返回,我们可以通过修改异步刷盘的频率来实现。设置参数log.flush.interval.messages=1,即每条消息都刷一次磁盘。这样的做法,Kafka也不会丢消息了,但是频繁的磁盘读写直接导致性能的下降。

另外,二者在服务恢复后,均出现了消息重复消费的情况,这说明消费位点的提交并不是同步落盘的。不过,幸好Kafka和RMQ都提供了自定义消费位点的接口,来避免大量的重复消费。

测试结论

  1. 在Broker进程被Kill的场景, Kafka和RocketMQ都能在保证吞吐量的情况下,不丢消息,可靠性都比较高。
  2. 在宿主机掉电的场景,Kafka与RocketMQ均能做到不丢消息,此时Kafka的吞吐量会急剧下跌,几乎不可用。RocketMQ则仍能保持较高的吞吐量。
  3. 在单机可靠性方面,RocketMQ综合表现优于Kafka。

附录:

测试环境

服务端为单机部署,机器配置如下:

应用版本:

测试脚本

同步刷盘和异步刷盘的区别

同步刷盘是在每条消息都确认落盘了之后才向发送者返回响应;而异步刷盘中,只要消息保存到Broker的内存就向发送者返回响应,Broker会有专门的线程对内存中的消息进行批量存储。所以异步刷盘的策略下,当机器突然掉电时,Broker内存中的消息因无法刷到磁盘导致丢失。

### 数据可靠性比较 #### Kafka 的数据可靠性机制 Kafka 提供了多种配置选项来确保消息传递的可靠性。生产者可以设置 `acks` 参数以控制确认行为,当此参数设为 `all` 时,只有当所有同步副本都已写入日志后才会向客户端发送确认响应[^1]。 为了进一步增强系统的容错能力,Kafka 支持 ISR (In-Sync Replicas) 列表的概念,在发生故障转移期间能够保持高可用性一致性。此外,通过调整 `min.insync.replicas` 其他相关参数可实现更严格的消息持久化保障措施。 #### RocketMQ 的数据可靠性设计 RocketMQ 同样重视数据的安全存储传输,并采用了独特的刷盘策略以及 Master/Slave 架构来进行灾难恢复处理。默认情况下,它会采用异步刷盘方式提高吞吐量;而对于那些对延迟敏感的应用场景,则可以选择同步双写模式以牺牲部分性能换取更强的一致性保护[^2]。 另外值得注意的是,RocketMQ 还引入了 Slave 只读特性,允许消费者直接从备节点拉取消息,从而减轻主节点的压力并提升整体集群的服务质量。 综上所述,虽然两者都能提供较高的数据可靠性水平,但在具体实施细节方面存在差异: - **复制机制**: Kafka 使用 ISR 来维护多个副本来保证分区内的数据一致性高可用性; - **刷盘策略**: RocketMQ 默认采取异步刷盘降低磁盘 I/O 开销,同时也支持同步双写的强一致性方案; - **消费模型**: RocketMQ 中 Slave 节点可以直接参服务请求分担流量压力,而 Kafka 主要依赖于 Consumer Group 协议完成负载均衡工作。 因此,在选择合适的技术栈之前应当充分考虑业务需求特点及预期目标等因素的影响。 ```python # Python伪代码展示如何配置Kafka producer acks参数 from kafka import KafkaProducer producer = KafkaProducer(bootstrap_servers='localhost:9092', acks='all') # 设置acks=all确保最高级别的可靠性 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值