相同之处

  • 两者底层原理有很多相似之处,RocketMQ 借鉴了 Kafka 的设计。
  • 两者均利用了操作系统 Page Cache 的机制,同时尽可能通过顺序 io 降低读写的随机性,将读写集中在很小的范围内,减少缺页中断,进而减少了对磁盘的访问,提高了性能。

    不同之处

    存储形式

  • Kafka 采用 partition,每个 topic 的每个 partition 对应一个文件。顺序写入,定时刷盘。但一旦单个 broker 的 partition 过多,则顺序写将退化为随机写,Page Cache 脏页过多,频繁触发缺页中断,性能大幅下降。

  • RocketMQ 采用 CommitLog+ConsumeQueue,单个 broker 所有 topic 在 CommitLog 中顺序写,Page Cache 只需保持最新的页面即可。同时每个 topic 下的每个 queue 都有一个对应的 ConsumeQueue 文件作为索引。ConsumeQueue 占用 Page Cache 极少,刷盘影响较小。

    存储可靠性

  • RocketMQ 支持异步刷盘,同步刷盘,同步 Replication,异步 Replication。

  • Kafka 使用异步刷盘,异步 Replication。

    顺序消息

    Kafka 和 RocketMQ 都仅支持单 topic 分区有序。RocketMQ 官方虽宣称支持严格有序,但方式为使用单个分区。

    延时消息

  • RocketMQ 支持固定延时等级的延时消息,等级可配置。

  • kfaka 不支持延时消息。

    消息重复

  • RocketMQ 仅支持 At Least Once。

  • Kafka 支持 At Least Once、Exactly Once。

    消息过滤

  • RocketMQ 执行过滤是在 Broker 端,支持 tag 过滤及自定义过滤逻辑。

  • Kafka 不支持 Broker 端的消息过滤,需要在消费端自定义实现。

    消息失败重试

  • RocketMQ 支持定时重试,每次重试间隔逐渐增加。

  • Kafka 不支持重试。

    DLQ(dead letter queue)

  • RocketMQ 通过 DLQ 来记录所有消费失败的消息。

  • Kafka 无 DLQ。Spring 等第三方工具有实现,方式为将失败消息写入一个专门的 topic。

    回溯消费

  • RocketMQ 支持按照时间回溯消费,实现原理与 Kafka 相同。

  • Kafka 需要先根据时间戳找到 offset,然后从 offset 开始消费。

    事务

  • RocketMQ 支持事务消息,采用二阶段提交 + broker 定时回查。但也只能保证生产者与 broker 的一致性,broker 与消费者之间只能单向重试。即保证的是最终一致性。

  • Kafka 从 0.11 版本开始支持事务消息,除支持最终一致性外,还实现了消息 Exactly Once 语义(单个 partition)。

    服务发现

  • RocketMQ 自己实现了 namesrv。

  • Kafka 使用 ZooKeeper。

    高可用

  • RocketMQ 在高可用设计上粒度只控制在 Broker。其保证高可用是通过 master-slave 主从复制来解决的。

  • Kafka 控制高可用的粒度是放在分区上。每个 topic 的 leader 分区和 replica 分区都可以在所有 broker 上负载均衡的存储。
  • Kafka 的这种设计相比 RocketMQ 这种主从复制的设计有以下好处:
    • Kafka 中不需要设置从 broker,所有的 broker 都可以收发消息。负载均衡也做的更好。
    • Kafka 的分区选举是自动做的,RocketMQ 需要自己指定主从关系。
    • Kafka 分区的复制份数指定为 N,则可以容忍 N-1 个节点的故障。发生故障只需要分区 leader 选举下即可,效率很高。