kafka做为流式处理的上一层,为何吞吐量那么大?

Kafka为何速度快、吞吐量大

Kafka是大数据领域无处不在的消息中间件,目前普遍使用在企业内部的实时数据管道,并帮助企业构建本身的流计算应用程序。Kafka虽然是基于磁盘作的数据存储,但却具备高性能、高吞吐、低延时的特色,其吞吐量动辄几万、几十上百万。可是不少使用过Kafka的人,常常会被问到这样一个问题,Kafka为何速度快,吞吐量大;大部分被问的人都是一会儿就懵了,或者是只知道一些简单的点,本文就简单的介绍一下Kafka为何速度快,吞吐量大。linux

1、顺序读写

众所周知Kafka是将消息记录持久化到本地磁盘中的,通常人会认为磁盘读写性能差,可能会对Kafka性能如何保证提出质疑。实际上不论是内存仍是磁盘,快或慢关键在于寻址的方式,磁盘分为顺序读写与随机读写,内存也同样分为顺序读写与随机读写。基于磁盘的随机读写确实很慢,但磁盘的顺序读写性能却很高,通常而言要高出磁盘随机读写三个数量级,一些状况下磁盘顺序读写性能甚至要高于内存随机读写,这里给出著名学术期刊 ACM Queue 上的一张性能对比图:
kafka做为流式处理的上一层,为何吞吐量那么大?缓存

磁盘的顺序读写是磁盘使用模式中最有规律的,而且操做系统也对这种模式作了大量优化,Kafka就是使用了磁盘顺序读写来提高的性能。Kafka的message是不断追加到本地磁盘文件末尾的,而不是随机的写入,这使得Kafka写入吞吐量获得了显著提高 。网络

2、Page Cache

为了优化读写性能,Kafka利用了操做系统自己的Page Cache,就是利用操做系统自身的内存而不是JVM空间内存。这样作的好处有:数据结构

  • 避免Object消耗:若是是使用 Java 堆,Java对象的内存消耗比较大,一般是所存储数据的两倍甚至更多。
  • 避免GC问题:随着JVM中数据不断增多,垃圾回收将会变得复杂与缓慢,使用系统缓存就不会存在GC问题

相比于使用JVM或in-memory cache等数据结构,利用操做系统的Page Cache更加简单可靠。首先,操做系统层面的缓存利用率会更高,由于存储的都是紧凑的字节结构而不是独立的对象。其次,操做系统自己也对于Page Cache作了大量优化,提供了 write-behind、read-ahead以及flush等多种机制。再者,即便服务进程重启,系统缓存依然不会消失,避免了in-process cache重建缓存的过程。socket

经过操做系统的Page Cache,Kafka的读写操做基本上是基于内存的,读写速度获得了极大的提高。分布式

3、零拷贝

这里主要讲的是Kafka利用 linux 操做系统的 “零拷贝(zero-copy)” 机制在消费端作的优化。首先来了解下数据从文件发送到socket网络链接中的常规传输路径:ide

  • 操做系统从磁盘读取数据到内核空间( kernel space )的Page Cache
  • 应用程序读取Page Cache的数据到用户空间(user space)的缓冲区
  • 应用程序将用户空间缓冲区的数据写回内核空间到socket缓冲区( socket buffer )
  • 操做系统将数据从socket缓冲区复制到网络发送的NIC缓冲区

这个过程包含4次copy操做和2次系统上下文切换,性能其实很是低效。linux操做系统 “零拷贝” 机制使用了sendfile方法, 容许操做系统将数据从Page Cache 直接发送到网络,只须要最后一步的copy操做将数据复制到 NIC 缓冲区, 这样避免从新复制数据 。示意图以下:性能

kafka做为流式处理的上一层,为何吞吐量那么大?

经过这种 “零拷贝” 的机制,Page Cache 结合 sendfile 方法,Kafka消费端的性能也大幅提高。这也是为何有时候消费端在不断消费数据时,咱们并无看到磁盘io比较高,此刻正是操做系统缓存在提供数据。大数据

4、分区分段

Kafka的message是按topic分类存储的,topic中的数据又是按照一个一个的partition即分区存储到不一样broker节点。每一个partition对应了操做系统上的一个文件夹,partition实际上又是按照segment分段存储的。这也很是符合分布式系统分区分桶的设计思想。优化

经过这种分区分段的设计,Kafka的message消息其实是分布式存储在一个一个小的segment中的,每次文件操做也是直接操做的segment。为了进一步的查询优化,Kafka又默认为分段后的数据文件创建了索引文件,就是文件系统上的.index文件。这种分区分段+索引的设计,不只提高了数据读取的效率,同时也提升了数据操做的并行度。

总结

Kafka采用顺序读写、Page Cache、零拷贝以及分区分段等这些设计,再加上在索引方面作的优化,另外Kafka数据读写也是批量的而不是单条的,使得Kafka具备了高性能、高吞吐、低延时的特色。这样,Kafka提供大容量的磁盘存储也变成了一种优势。

相关文章
相关标签/搜索