kafka内部,消息都是以“批”为单位处理的。
消息在kafka中的流转:
发送端(Producer)构建批消息和解开批消息分别在发送端和消费端的客户端完成,不仅减轻了Broker的压力,最重要的是减少了Broker处理请求的次数,提升了总体的处理能力。
2. 使用顺序读写提升磁盘IO性能对于磁盘,顺序读写性能远远好于随机读写。顺序读写相比随机读写省去了大部分的寻址时间,它只需要寻址一次。
Kafka利用了这个存储特性。存储设计简单,对于每个分区,它把从Producer收到的消息,顺序地写入对应log文件,一个文件写满后,开启一个新的文件这样顺序写下去。消费的时候,也顺序的读取。
PageCache就是操作系统在内存中给磁盘的文件建立缓存。在调用系统的API读写文件是,不会直接读取磁盘上的,而是操作的是PageCache,也就是文件在内存中缓存的副本。
写文件:数据 — 写入 —> 内存的PageCache ——一批一批写入—— > 磁盘
读文件:从PageCache中读取数据
使用完PageCache后,不会立即清除,而是尽可能利用空闲内存保留,内存不足时,使用清理策略(LRU或者它的变种算法)清理掉部分PageCache。保留逻辑:优先保留最近一段时间最常使用的PageCache。
大部分情况下,消费读消息都会命中PageCache,好处:
读取的速度非常快 给写入消息让出磁盘的IO资源,简介提升了写入的性能 4. ZeroCopy: 零拷贝技术在服务端,处理消费的大致逻辑:
从文件中找到消息数据,读到内存中 把消息通过网络发给客户端这个过程数据实际做了2次或者3次复制:
从文件复制到PageCache中,如果命中PageCache,这一步可以省掉; 从PageCache复制到应用程序的内存空间中,也就是我们可以操作的对象所在的内存; 从应用程序的内存空间复制到Socket的缓冲区,这个过程就是调用网络应用框架的API发送数据的过程kafka利用零拷贝技术可以减少一次复制,2、3步骤合并为一次。直接从PageCache中把数据复制到Socket缓冲区,减少一次复制,由于不用把数据复制到用户内存空间,DMA控制器可以直接完成数据复制,不需要CPU参与,速度更快。
系统调用:
#include
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
前两个参数:目的端和远端的文件描述符,后两个参数:远端的偏移量和复制数据的长度,返回值是实际复制数据的长度。