聊完两种零拷贝技术,我们回过头来看下 kafka 为什么性能比 RocketMQ 好。这是因为 RocketMQ 使用的是 mmap 零拷贝技术,而 kafka 使用的是 sendfile。kafka 以更少的拷贝次数以及系统内核切换次数,获得了更高的性能。但问题又来了,为什么 RocketMQ 不使用 sendfile?参考 kafka 抄个作业也不难啊?我们来看下 sendfile 函数长啥样。
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
// num = sendfile(xxx);
再来看下 mmap 函数长啥样。
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
// buf = mmap(xxx)
注释里写的是两个函数的用法,mmap 返回的是数据的具体内容,应用层能获取到消息内容并进行一些逻辑处理。
而 sendfile 返回的则是发送成功了几个字节数,具体发了什么内容,应用层根本不知道。
而 RocketMQ 的一些功能,却需要了解具体这个消息内容,方便二次投递等,比如将消费失败的消息重新投递到死信队列中,如果 RocketMQ 使用 sendfile,那根本没机会获取到消息内容长什么样子,也就没办法实现一些好用的功能了。
而 kafka 却没有这些功能特性,追求极致性能,正好可以使用 sendfile。
除了零拷贝以外,kafka 高性能的原因还有很多,比如什么批处理,数据压缩啥的,但那些优化手段 rocketMQ 也都能借鉴一波,唯独这个零拷贝,那是毫无办法。