文章收录地址:Java-Bang 专一于零碎架构、高可用、高性能、高并发类技术分享
除了音讯程序追加、页缓存等技术,Kafka 还应用 零拷贝技术 来进一步晋升性能。所谓的零拷贝是指将数据间接从磁盘文件复制到网卡设施中,而不须要经由应用程序之手。零拷贝大大提高了应用程序的性能,缩小了内核和用户模式之间的上下文切换。对 Linux 操作系统而言,零拷贝技术依赖于底层的 sendfile() 办法实现。对应于 Java 语言,FileChannal.transferTo() 办法的底层实现就是 sendfile() 办法。
单纯从概念上了解“零拷贝”比拟形象,这里简略地介绍一下它。思考这样一种罕用的情景:你须要将动态内容(相似图片、文件)展现给用户。这个情景就意味着须要先将动态内容从磁盘中复制进去放到一个内存 buf 中,而后将这个 buf 通过套接字(Socket)传输给用户,进而用户取得动态内容。这看起来再失常不过了,但实际上这是很低效的流程,咱们把下面的这种情景形象成上面的过程:
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
首先调用 read() 将动态内容(这里假如为文件 A)读取到 tmp_buf,而后调用 write() 将 tmp_buf 写入 Socket,如下图所示。
在这个过程中,文件 A 经验了 4 次复制 的过程:
- 调用 read() 时,文件 A 中的内容被复制到了内核模式下的 Read Buffer 中。
- CPU 管制将内核模式数据复制到用户模式下。
- 调用 write() 时,将用户模式下的内容复制到内核模式下的 Socket Buffer 中。
- 将内核模式下的 Socket Buffer 的数据复制到网卡设施中传送。
从下面的过程能够看出,数据平白无故地从内核模式到用户模式“走了一圈”,节约了 2 次复制过程:第一次是从内核模式复制到用户模式;第二次是从用户模式再复制回内核模式,即下面 4 次过程中的第 2 步和第 3 步。而且在下面的过程中,内核和用户模式的上下文的切换也是 4 次。
如果采纳了零拷贝技术,那么应用程序能够间接申请内核把磁盘中的数据传输给 Socket,如下图所示。
零拷贝技术通过 DMA(Direct Memory Access)技术将文件内容复制到内核模式下的 Read Buffer 中。不过没有数据被复制到 Socket Buffer,相同只有蕴含数据的地位和长度的信息的文件描述符被加到 Socket Buffer 中。DMA 引擎间接将数据从内核模式中传递到网卡设施(协定引擎)。这里数据只经验了 2 次复制就从磁盘中传送进来了,并且上下文切换也变成了 2 次。零拷贝是针对内核模式而言的,数据在内核模式下实现了零拷贝。
要把握 Kafka 的外围实现原理,不仅仅只是 Kafka 的日志格局、日志索引、日志清理等方面的内容,也蕴含底层物理存储相干的知识点。这样能力对 Kafka 的整顿实现脉络有比拟清晰的认知。加油吧~ 打工人!