io读取一个文件再写入socket技术_Kafka实现高性能IO的“独门绝技”

一、使用批量消息提升服务端处理能力

    批处理是提升系统吞吐量的有效方法。在Kafka内部,消息都是以“批”为单位处理的。

    在Producer(发送端),应用程序调用send()发送一条消息后,无论是同步发送还是异步发送,Kafka都不会立即把这条消息发送出去。它会先把这条消息存放在内存中缓存起来,然后选择合适的时机把缓存中所有的消息组成一批,一次性发送给Broker。通俗说就是攒一波再发送。

    在Broker(服务端),Kafka不会把一批消息还原成多条消息,而是把每批消息当成一个“批消息”来处理。也就是说,在Broker的整个处理流程中,无论是写入磁盘、从磁盘中读出来、还是复制到其他副本,批消息都不会被解开,一直作为一个一条“批消息”来进行处理。

    在消费时,消息同样是以批为单位进行传递的,Consumer从Broker拉到一批消息后,在客户端把批消息解开,再一条一条交给应用程序代码处理。

    构件批消息和解开批消息分别在发送端和消费端的客户端完成,不仅减轻了Broker的压力,最重要的是减少了Broker处理请求的次数,提升了总体的处理能力。

二、使用顺序读写提升磁盘IO性能

    众所周知,对于磁盘来说,顺序读写的性能要远远好于随机读写。因为顺序读写只有一次寻址时间,而随机读写,每读一次都需要一次寻址时间。

    磁盘大致结构图如下:

4c25dac5ea2de60ee6280c1d589b301a.png

    Kafka充分利用了磁盘的这个特性,它的存储设计的非常简单,对于每个分区,它把从Producer收到的消息,顺序的写入对应的log文件中,一个文件写满了就开启一个新的文件,这样顺序写下去。消费的时候,也是从某个全集的位置开始,也就是某一个log文件的某个位置,顺序的把消息读出来。

    这样一个简单的设计,充分利用了顺序读写的特性,大大的提升了Kafka在使用磁盘时的IO性能。

三、利用PageCache加速消息的读写

    通俗的说,PageCache就是操作系统在内存中给磁盘上的文件建立的缓存。无论我们使用何种语言编写的程序,在调用系统API读写文件时,并不会直接去读写磁盘上的文件,应用程序实际操作的都是PageCache,也就是文件在内存中的缓存的副本。

    应用程序在写入文件的时候,操作系统会先把数据写入到内存中的PageCache,然后在合适的时机再一批一批的写入到磁盘上。

    应用程序在读取文件时也是从PageCache中来读取数据,这时候就会出现两种情况。

    如果PageCache中有数据,那就直接读取,这样就免去了从磁盘上读取数据的时间;如果PageCache中没有数据,这时候操作系统就会触发一个缺页中断,应用程序的读取线程会被阻塞,操作系统将数据从磁盘文件中复制到PageCache中,然后应用程序再从PageCache中继续把数据读出来。

    应用程序在使用完某块PageCache后,操作系统不会立即将这个PageCache清除,而是尽可能的利用空闲的物理内存保存这些PageCache,除非系统内存不够用,操作系统才会清理掉一部分的PageCache,这就涉及到一些清理PageCache的策略,一般是使用LRU算法。

    Kafka就是利用了PageCache的这个特性,加速了消息读写速度。

四、ZeroCopy:零拷贝技术

    我们知道,在服务端,处理消费的大致逻辑是:

    1)从文件中找到消息数据,读到内存中;

    2)把消息通过网络发送给客户端。

    这个过程中,数据实际上做了2次或者3次的复制:

    1)从文件复制数据到PageCache中,如果命中PageCache,这一步可以省略;

    2)从PageCache复制到应用程序的内存空间;

    3)从应用程序的内存空间复制到Socket的缓冲区了,这个过程就是我们调用网络应用框架API发送数据的过程。

    Kafka使用零拷贝技术就可以把上面的复制次数减少一次,将上面的2、3步骤两次复制合并成一次复制,直接从PageCache中把数据复制到Socket缓冲区中,这样既减少一次数据复制,也不用CPU参与,直接由DMA控制器完成数据复制,速度更快。

======================================================

绿蚁新醅酒,红泥小火炉。

晚来天欲雪,能饮一杯无?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值