Kafka是Linkin开源的消息中间件
Kafka的设计目标是:
(1)以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。 (2)高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输。 (3)支持Kafka Server间的消息分区,及分布式消费,同时保证每个Partition内的消息顺序传输。 (4)同时支持离线数据处理和实时数据处理。 (5)Scale out:支持在线水平扩展。
RocketMQ是阿里开源的消息中间件
其最初也是基于Kafka发展而来。
数据可靠性
- RocketMQ支持异步实时刷盘,同步刷盘,同步Replication,异步Replication
- Kafka使用异步刷盘方式,异步Replication/同步Replication
性能对比
- Kafka会在Producer端将多个小消息合并,批量发向Broker,所以在批量发送消息时有着大量的优势,在批量时,Kafka单机写入TPS约在百万条/秒,消息大小100个字节
- RocketMQ单机写入TPS单实例约7万条/秒,RocketMQ在阿里使用在淘宝支付宝端,在处理异步消息需要保证消息到达,所以未实现api级别批量发送消息
单机支持的队列数
- Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长。
- RocketMQ单机支持最高5万个队列,Load不会发生明显变化
严格的消息顺序
- Kafka支持消息顺序,但是一台Broker宕机后,就会产生消息乱序
- RocketMQ支持严格的消息顺序,在顺序消息场景下,一台Broker宕机后,发送消息会失败,但是不会乱序
分布式事务消息
- Kafka不支持分布式事务消息
- 阿里云MQ支持分布式事务消息,未来开源版本的RocketMQ也有计划支持分布式事务消息
消息查询
- Kafka不支持消息查询
- RocketMQ支持根据Message Id查询消息,也支持根据消息内容查询消息(发送消息时指定一个Message Key,任意字符串,例如指定为订单Id)
总结:消息查询对于定位消息丢失问题非常有帮助,例如某个订单处理失败,是消息没收到还是收到处理出错了。
消息回溯
- Kafka理论上可以按照Offset来回溯消息
- RocketMQ支持按照时间来回溯消息,精度毫秒,例如从一天之前的某时某分某秒开始重新消费消息
总结:典型业务场景如consumer做订单分析,但是由于程序逻辑或者依赖的系统发生故障等原因,导致今天消费的消息全部无效,需要重新从昨天零点开始消费,那么以时间为起点的消息重放功能对于业务非常有帮助。
消费并行度
- Kafka的消费并行度依赖Topic配置的分区数,如分区数为10,那么最多10台机器来并行消费(每台机器只能开启一个线程),或者一台机器消费(10个线程并行消费)。即消费并行度和分区数一致。
- RocketMQ消费并行度分两种情况
- 顺序消费方式并行度同Kafka完全一致
- 乱序方式并行度取决于Consumer的线程数,如Topic配置10个队列,10台机器消费,每台机器100个线程,那么并行度为1000。
Broker端消息过滤
- Kafka不支持Broker端的消息过滤
- RocketMQ支持两种Broker端消息过滤方式
- 根据Message Tag来过滤,相当于子topic概念
- 向服务器上传一段Java代码,可以对消息做任意形式的过滤,甚至可以做Message Body的过滤拆分。
单机系统可靠性
- 模拟进程退出
在消息收发过程中,利用Kill -9 命令使Broker进程终止,然后重新启动,得到可靠性数据如下:
产品 | 刷盘策略 | 并发 | tps | 丢失 | 重复 |
---|---|---|---|---|---|
Kafka | 异步 | 3 | 600 | 不丢 | 不重复 |
Kafka | 异步 | 30 | 10500 | 不丢 | 不重复 |
Kafka | 异步 | 150 | 49200 | 不丢 | 重复7条 |
RocketMQ | 异步 | 1 | 4066 | 不丢 | 不重复 |
RocketMQ | 异步 | 3 | 10900 | 不丢 | 不重复 |
RocketMQ | 异步 | 140 | 52428 | 不丢 | 不重复 |
在Broker进程被终止重启,Kafka和RMQ都能保证同步发送的消息不丢,因为进程退出后操作系统能确保将该进程遗留在内存的数据刷到磁盘上。实验中,Kafka出现了极少量的消息重复。再次可以确定此场景中,二者的可靠性都很高。
- 模拟机器掉电
在消息收发过程中,直接拔掉Broker所在的宿主机电源,然后重启宿主机和Broker应用。因受到机房断电限制,我们在本场景测试中使用的是普通PC机器。得到可靠性数据如下:
产品 | 刷盘策略 | 并发 | tps | 丢失 | 重复 |
---|---|---|---|---|---|
Kafka | 异步 | 5 | 2000 | 丢失3条 | 掉电前所有发送重新消费 |
Kafka | 同步 | 5 | 300 | 不丢 | 重复3条 |
Kafka | 同步 | 60 | 500 | 不丢 | 重复2w条 |
RocketMQ | 异步 | 5 | 2500 | 丢失19条 | 不重复 |
RocketMQ | 同步 | 5 | 800 | 不丢 | 掉电前所有发送重新消费 |
RocketMQ | 同步 | 60 | 4000 | 不丢 | 掉电前所有发送重新消费 |
###测试结论
- 在Broker进程被Kill的场景, Kafka和RocketMQ都能在保证吞吐量的情况下,不丢消息,可靠性都比较高。
- 在宿主机掉电的场景,Kafka与RocketMQ均能做到不丢消息,此时Kafka的吞吐量会急剧下跌,几乎不可用。RocketMQ则仍能保持较高的吞吐量。
- 在单机可靠性方面,RocketMQ综合表现优于Kafka。