阿里口试:为什么kafka比RocketMQ吞吐量更高?

打印 上一主题 下一主题

主题 866|帖子 866|积分 2598

阿里中央件团队对 Kafka 和 RocketMQ 进行了性能压测,效果表现在雷同条件下,Kafka 的性能比 RocketMQ 快 50%左右。然而,RocketMQ 依然能每秒处理 10 万条消息,这表明它在性能上依然非常强大。那么,为什么 RocketMQ 参考了 Kafka 的架构,却无法与 Kafka 保持雷同的性能呢?以下是一些原因:
1.核心差异 mmap(内存映射) vs sendfile



  • Kafka:使用 sendfile 函数进行零拷贝,以淘汰数据拷贝次数和系统内核切换次数,从而获得更高的性能。sendfile 返回的是发送乐成的字节数,而应用层无法获取到消息内容。Kafka 以更少的拷贝次数以及系统内核切换次数,获得了更高的性能。
    但问题又来了,为什么 RocketMQ 不使用 sendfile?参考 Kafka 抄个作业也不难啊?我们来看下 sendfile 函数长啥样:
    1. ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
    2. // num = sendfile(xxx);
    复制代码
  • RocketMQ:使用 mmap 技术进行零拷贝,返回的是数据的具体内容,应用层可以获取消息内容并进行一些逻辑处理。我们来看下 mmap 函数长啥样:
    1. void *mmap(void *addr, size_t length, int prot, int flags,
    2.            int fd, off_t offset);
    3. // buf = mmap(xxx)
    复制代码
    注释里写的是两个函数的用法,mmap 返回的是数据的具体内容,应用层能获取到消息内容并进行一些逻辑处理。而 sendfile 返回的则是发送乐成了几个字节数,具体发了什么内容,应用层根本不知道。
    RocketMQ 的一些功能需要相识具体这个消息内容,方便二次投递等,比如将消耗失败的消息重新投递到死信队列中。假如 RocketMQ 使用 sendfile,那根本没时机获取到消息内容长什么样子,也就没办法实现一些好用的功能了。而 Kafka 却没有这些功能特性,追求极致性能,恰好可以使用 sendfile。
操作步骤对比


传统IO使用 read 和 write 的步骤


  • 从磁盘读取数据

    • 步伐发起系统调用 read(),实验读取磁盘数据。
    • 数据从磁盘设备拷贝到内核空间的缓冲区。
    • 数据再从内核空间的缓冲区拷贝到用户空间的缓冲区。

  • 将数据发送到网络

    • 步伐发起系统调用 write(),将用户空间的缓冲区数据发到网络。
    • 数据从用户空间拷贝到 socket 发送缓冲区。
    • 数据再从 socket 发送缓冲区拷贝到网卡。

  • 终极数据通过网络到达消耗者
使用 mmap 的步骤

mmap 作为一种零拷贝技术,指的是用户空间到内核空间这个过程不需要拷贝,而不是指数据从磁盘到发送到网卡这个过程零拷贝。

  • 从磁盘读取数据

    • 步伐发起系统调用 mmap(),将磁盘文件映射到内存。
    • 数据从磁盘设备拷贝到内核空间的缓冲区。
    • 内核空间的缓冲区映射到用户空间,这里不需要额外的数据拷贝。

  • 将数据发送到网络

    • 步伐发起系统调用 write(),将映射的内存数据发到网络。
    • 数据从内核空间的缓冲区拷贝到 socket 发送缓冲区。
    • 数据再从 socket 发送缓冲区拷贝到网卡。

  • 终极数据通过网络到达消耗者
使用 sendfile 的步骤

这里的零拷贝指的是零 CPU拷贝。也就是说 sendfile 场景下,需要的两次拷贝,都不是 CPU 直接参与的拷贝,而是其他硬件设备技术做的拷贝,不延长我们 CPU 跑步伐。

  • 从磁盘读取数据并发送

    • 步伐发起系统调用 sendfile(),内核会直接从磁盘读取数据并将其发送到网络。
    • 数据从磁盘设备拷贝到内核空间的缓冲区。
    • 内核空间缓冲区里的数据可以直接拷贝到网卡,淘汰了拷贝次数和系统调用的开销。

  • 终极数据通过网络到达消耗者
2. 布局差异



  • Kafka:使用一个简单的日记存储模型,其中每个主题分区是一个一连的日记。消息被追加到日记文件的末尾,一旦写入就不可改变。这种追加模式极大地优化了磁盘 I/O,因为磁盘写入操作最高效的方式是顺序写入。
  • RocketMQ:在存储层面采用了更为复杂的设计,支持多种存储和索引机制,以便支持广泛的功能,如定时消息和事务消息。这些功能需要在存储系统中实现额外的逻辑,大概影响根本的消息通报性能。
3. 设计目的不同



  • Kafka:其设计哲学是保持简单,只管淘汰对消息的处理,直接使用文件系统和网络栈的高效功能。Kafka 追求极致性能,因此其架构设计非常简洁。
  • RocketMQ:提供了更多的灵活性和精细控制,尤其是在消息过滤和服务质量保证上。RocketMQ 的设计考虑了更多的企业级特性和复杂的消息处理需求,这大概在某些场合下牺牲了一部门吞吐量。
4. 数据复制和划一性机制



  • Kafka:使用了一个简化的复制机制,通过 “leader-follower” 模型来同步数据。所有写入操作都先在 leader 上实行,然后异步复制到 follower。这种方法淘汰了写操作的等待时间,并提高了数据写入的吞吐量。
  • RocketMQ:使用雷同的复制机制,但其更复杂的消息路由和存储机制大概增加了额外的开销。比方,RocketMQ 支持更多级别的消息可靠性和复杂的事务管理,这些都大概在提供更高服务质量的同时影响吞吐量。
5. 内存和资源管理



  • Kafka:优化了内存的使用,只管利用操作系统的页缓存,淘汰了 JVM 堆内存的压力。这种设计使得 Kafka 能够高效地处理更大量的数据,同时维持低耽误。
  • RocketMQ:对内存和资源的管理也很有效,但它的功能丰富性大概需要更多的资源调整和管理,这在高负载情况下大概影响性能。
6. 消耗者模型



  • Kafka:采用拉(pull)模型,允许消耗者根据自己的处理能力来拉取数据,这种方式在处理大量数据时可以更好地控制内存和资源使用。
  • RocketMQ:通常也使用拉模型,但它提供了更多的推(push)模式配置选项,这可以更实时地传输消息,但在非常高的吞吐量需求下,推模式大概导致消耗者端压力增大。
总结



  • RocketMQ 和 Kafka 相比,在架构上做了减法,在功能上做了加法:RocketMQ 简化了协调治点和分区以及备份模型,同时增强了消息过滤、消息回溯和事务能力,加入了耽误队列、死信队列等新特性。
  • 凡事皆有代价:RocketMQ 牺牲了一部门性能,调换了比 Kafka 更强大的功能特性。
尽管 RocketMQ 参考了 Kafka 的架构,但由于在设计上的不同目的、布局差异以及实现细节上的不同,RocketMQ 在性能上无法完全达到 Kafka 的程度。Kafka 在设计上的简化、对磁盘 I/O 的优化以及高效的数据复制策略,使得它在高吞吐量场景下体现更优。而 RocketMQ 在提供更多企业级功能和服务质量保证的同时,牺牲了一部门性能,但依然体现精彩,每秒处理 10 万条消息,证明其强大的处理能力和灵活性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表