Kafka的高吞吐

  Kafka诞生于Linkin公司。当时Linkin需要对用户和网站上产生的活动数据进行处理,什么是活动数据呢?比如页面访问量、用户行为、搜索情况等,对这些数据的分析将被应用于广播、排序、个性化 推荐、运营监控等。这类数据有个特点,需要实时处理,最好当下用户的一些行为数据能马上被后台感知、计算,并给出一些推荐等等,另外一个是数据量大,毫无疑问,每个用户的活动数据是远远多于诸如表单这样的业务数据的,而Linkin对这类数据采用传统的批处理方法显然是不能符合需求的,前端服务器先写文件,然后通过批量的方式送入Hadoop这样的大数据分析器里慢慢整。于是乎Linkin便开发了Kafka专门处理这类数据,这类数据的特点决定了Kafka需要做到低延时处理海量数据,实际上Kafka的一大特点就是高吞吐,在普通的廉价虚拟机器上,据Linkin统计,最新数据是每天利用Kafka处理一万亿条数据,峰值时每秒会发布百万条数据。它的快和在存储和网络上做的优化不无关系。

    能够存储到几乎无限大的磁盘空间而无需付出性能代价是kafka的一大法宝,意味着它有着从容面对海量数据的能力。

    Kafka的消息存储是严重依赖于文件系统的,消息持久化时只是简单的文件读写。这种方式有个优势,操作的复杂度都是O(1),读写操作互不干扰,这样性能就完全同数据大小脱离的关系,数据量大简单加磁盘就行了。从直觉来看,读写磁盘速度会很慢,实际上由于Kafka采用了顺序读写磁盘的方式,这种I/O的效率并不慢,某些情况下比操作内存更快。

     相对于人们传统的直觉,磁盘的吞吐性能可快可慢,这取决于磁盘的使用方式,在一个由6个7200rpm的SATA硬盘组成的RAID-5磁盘阵列上,线性写入(linear write)的速度大约是300MB/秒,但随即写入却只有50k/秒,其中的差别接近10000倍。这是由于随即写入时磁盘需要再次寻道,严重影响了读写的效能,再加之操作系统采用预读和预写的方式对磁盘读写进行优化,进一步提升了顺序读写磁盘的效率。

   Kafka充分利用了文件系统这一特性。

Kafka的高吞吐_第1张图片

  这是某个Kafka节点收发消息图。Partition是消息收发的主体,每一个broker内部都至少有一个Partiton。

Kafka的高吞吐_第2张图片

   这是Partition的存储结构图,每个Partition都被分成了若干个Segment,而每个Segment又由log和index文件组成。log文件用来存储Produces推送的消息,index是消息的索引。从这个结构图可以看出,在Partition中以log文件的形式存在。每一个推送到Partition中的消息都会以追加的形式存到这个文件中,这些消息不是立即刷新到磁盘上的,而是按照操作系统预写的方式存到了内存的页面缓存里,等达到一定量级,再由flush到磁盘上,让Partition支持线性写入。

   在读消息时,Kafka规定每个Partition只能同时给一个Consumer推送消息。这一设计避免了在同一个Partition多个Consumer对数据对竞争,降低了磁头移动的几率,让Partition尽可能按照线性读盘的方式获取数据,提高吞吐量。

   除了消息大容量之外,Kafka在网络传输上的零拷贝是另一大法宝,这种优化让消息的使用速度接近网络连接的极限。

   零拷贝的方式主要应用在消息发送上。我们知道平常我们要把磁盘里的数据依靠网络发送出去要经历4个阶段:

   1、操作系统从磁盘中读取数据到内核空间的页面缓存

   2、应用程序将数据从页面缓存拷贝到应用程序空间

   3、应用程序将数据拷贝到socket内核空间

   4、操作系统将数据从socket缓冲区拷贝到网卡中,经网络发送

   从磁盘里发送一次数据要经历四次拷贝,显然会降低数据发送的效率,Kafka将这四步简化到了一步,直接从内存的页面缓存中拷贝到网卡发送出去,只有一次拷贝,可想而知它的效率有多高。

   近乎无限的数据容量加上接近带宽极限的消息发布速率,使单个机子的吞吐量达到了极限,但这还不是高吞吐秘密的全部,下一节将从集群的角度剖析高吞吐的奥秘。

你可能感兴趣的:(中间件)