理论教育 Scala语言基础与开发实战:提升Kafka的高效性

Scala语言基础与开发实战:提升Kafka的高效性

时间:2023-11-24 理论教育 版权反馈
【摘要】:Kafka为了提高效率,对这两个问题进行了优化,比如围绕消息集合的概念来构建Kafka的API,即一次网络请求发送一个消息集合,而不是每次只发一条消息。如Kafka中MessageSet的实现本身是一个非常简单的API,它将一个字节数组或者文件进行直接打包传输,对消息的处理并没有分开的序列化和反序列化步骤。这种机制大大提高了Kafka的数据传输效率。

Scala语言基础与开发实战:提升Kafka的高效性

这里假设消息的数据量特别大,同时确保每一条被发送的消息至少可以被读一次,那么是什么原因导致数据低效传输呢?主要就是如下两个原因:第一,数据消息传输时,有过多的网络请求;第二,数据消息传输时,有过多的字节复制。

Kafka为了提高效率,对这两个问题进行了优化,比如围绕消息集合的概念来构建Kaf⁃ka的API,即一次网络请求发送一个消息集合,而不是每次只发一条消息。如Kafka中Mes⁃sageSet的实现本身是一个非常简单的API,它将一个字节数组或者文件进行直接打包传输,对消息的处理并没有分开的序列化和反序列化步骤。由Broker保存的消息日志本身只是一个消息集合的目录,这些消息已经被写入磁盘。这种抽象允许单一一个字节可以被Broker和Consumer所分享。维护这样的通用格式可以对大多数重要的操作进行优化,持久日志数据块的网络传输等。现在的UNIX操作系统提供一种高优化的代码路径将数据从页缓存传到一个套接字(socket);在Linux中,这可以通过调用sendfile系统来完成。Java提供了访问这个系统调用的方法:FileChannel.transferTo。

为了理解sendfile的影响,需要理解一般的将数据从文件传到套接字的路径:

1)操作系统将数据从磁盘读到内核空间的页缓存中。

2)应用将数据从内核空间读到用户空间的缓存中。(www.daowen.com)

3)应用将数据写回内存空间的套接字缓存中。

4)操作系统将数据从套接字缓存写到网卡缓存中,以便将数据通过网络发送出去。

这样做明显是低效的,这里有4次复制、两次系统调用。如果使用sendfile,再次复制可以被避免:允许操作系统将数据直接从页缓存发送到网络上。所以在这个优化的路径中,只有最后一步将数据复制到网卡缓存中是需要的。

对于期望一个主题上有多个消费者是一种常见的应用场景。利用上述的零复制,数据只被复制到页缓存一次,然后就可以在每次消费时被重复利用,而不需要将数据存在内存中,然后在每次读的时候复制到内核空间中,这使得消息消费速度可以达到网络连接的速度。这种机制大大提高了Kafka的数据传输效率。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈