Kafka-Pagecache原理

一、Kafka PageCache简介

Kafka重度依赖底层操作系统提供的PageCache功能。当上层有写操作时,操作系统只是将数据写入PageCache,同时标记Page属性为Dirty。当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。同时如果有其他进程申请内存,回收PageCache的代价又很小,所以现代的OS都支持PageCache。

使用PageCache功能同时可以避免在JVM内部缓存数据,JVM为我们提供了强大的GC能力,同时也引入了一些问题不适用与Kafka的设计。

如果在Heap内管理缓存,JVM的GC线程会频繁扫描Heap空间,带来不必要的开销。如果Heap过大,执行一次Full GC对系统的可用性来说将是极大的挑战。

所有在JVM内的对象都不免带有一个Object Overhead(千万不可小视),内存的有效空间利用率会因此降低。

所有的In-Process Cache在OS中都有一份同样的PageCache。所以通过将缓存只放在PageCache,可以至少让可用缓存空间翻倍。

如果Kafka重启,所有的In-Process Cache都会失效,为了防止内存中的数据随着kafka重启而丢失,因此Kafka将消息数据存储在PageCache中,而在遇到上述状况,Kafka重启后,OS管理的PageCache依然可以继续使用。

二、Kafka Sendfile技术

PageCache还只是第一步,Kafka为了进一步的优化性能还采用了Sendfile技术。在解释Sendfile之前,首先介绍一下传统的网络I/O操作流程,大体上分为以下4步。

  1. OS 从硬盘把数据读到内核区的PageCache。
  2. 用户进程把数据从内核区Copy到用户区。
  3. 然后用户进程再把数据写入到Socket,数据流入内核区的Socket Buffer上。
  4. OS 再把数据从Buffer中Copy到网卡的Buffer上,这样完成一次发送。

传统IO流程

整个过程共经历两次Context Switch,四次System Call。同一份数据在内核Buffer与用户Buffer之间重复拷贝,效率低下。其中2、3两步没有必要,完全可以直接在内核区完成数据拷贝。这也正是Sendfile所解决的问题,经过Sendfile优化后,整个I/O过程就变成了下面这个样子。

Kafka的IO流程

通过以上的介绍不难看出,Kafka的设计初衷是尽一切努力在内存中完成数据交换,无论是对外作为一整个消息系统,或是内部同底层操作系统的交互。如果Producer和Consumer之间生产和消费进度上配合得当,完全可以实现数据交换零I/O。这也就是为什么说Kafka使用“硬盘”并没有带来过多性能损失的原因。

三、Tips

  1. Kafka官方并不建议通过Broker端的log.flush.interval.messages和log.flush.interval.ms来强制写盘,认为数据的可靠性应该通过Replica来保证,而强制Flush数据到磁盘会对整体性能产生影响。
  2. 可以通过调整/proc/sys/vm/dirty_background_ratio和/proc/sys/vm/dirty_ratio来调优性能。
  3. 脏页率超过第一个指标会启动pdflush开始Flush Dirty PageCache。
  4. 脏页率超过第二个指标会阻塞所有的写操作来进行Flush。
  5. 根据不同的业务需求可以适当的降低dirty_background_ratio和提高dirty_ratio。

四、结论

  1. Kafka在运行过程中,会尽可能多的把空闲内存都当做了磁盘缓存来使用。
  2. 当上层有写操作时,操作系统只是将数据写入PageCache,同时标记Page属性为Dirty。
  3. 当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。
  4. 同时如果有其他进程申请内存,会回收抢占一部分PageCache,但也会导致Kafka吞吐量下降会不稳定。这个我们做过相应的测试工作。
  5. Kafka使用PageCache功能同时可以避免在JVM内部缓存数据
  6. Kafka重启后,OS管理的PageCache不会被释放,依然可以继续使用。
  7. Kafka使用了Sendfile技术,使数据交换的I/O过程均处于内核态运行。
  8. Kafka的刷盘机制,会将PageCache中的消息数据刷到磁盘当中,保证数据不会丢失。但这部分消息是否仍然存在PageCache中,这个我们不确定,需要后续通过阅读源码来解决。

五、参考文献

  1. http://www.dataguru.cn/article-9854-1.html
  2. http://www.linuxidc.com/Linux/2015-05/117022.htm
  3. https://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines

六、版权声明

转载请注明出处:https://shiyueqi.github.io/2017/04/27/Kafka-Pagecache原理/


Author: Yueqi Shi

Date: 2017-04-27 16:31:00 AM