刚才午睡了一会,做了一个梦,Kafka为什么"这么快",于是乎,便写了这篇探讨的博客文章,网上很多关于Kafka测试的文章,测试结果通常都是Kafka延迟吊打其他MQ,那么我们学习一个新东西的时候,首先会想到它会在我们的业务场景中有一个什么样的作用,为什么要用它而不用其他类似的组件,Kafka学习中,也会有这样的疑问。顺着这个逻辑,我们可能会有两个思路,第一,Kafka到底是什么?第二,Kafka的优点?有了这两个概念,我们就可以解决为什么要用它而不用其他组件的问题。
  阅读Kafka官方文档,寻找这两个问题的答案~

Kafka到底是什么?

ApacheKafka是一个分布式流媒体平台。
流媒体平台有三个关键功能:

  • 发布和订阅记录流,类似于消息队列或企业消息传递系统。
  • 以容错的持久方式存储记录流。
  • 记录发生时处理流。

Kafka通常用于两大类应用:

  • 构建可在系统或应用程序之间可靠获取数据的实时流数据管道。
  • 构建转换或响应数据流的实时流应用程序。

Kafka的优点?

  • 高吞吐,低延迟
  • 持久性、可靠性
  • 容错性
  • 高并发
  • 可扩展性

初步了解了Kafka之后,我们现在来一起探讨下Kafka低延迟的原理。

Kafka低延迟的原理

在上面的了解中,知道了Kafka有低延迟的优势,它是怎么实现的呢?下面就来一起探讨一下。
生产者(producer)写入数据
Kafka在收到消息的时候,会把消息持久化存储到硬盘中,为了优化写入速度,Kafka是这样设计的,顺序写入和运用页缓存技术。

  • 首先说一下,为什么顺序写入比随机写入快:先介绍一下它的存储原理。机械硬盘的结构你可以想象成一个唱片机,它有一个旋转的盘片和一个能沿半径方向移动的磁头。处理读取和写入请求时,首先可以根据请求的开始地址算出要处理的数据在磁盘上的位置,之后要进行以下几步工作:1、磁头沿半径方向移动,直至移动到数据所在的柱面(相同半径的磁道组成的环面)2、盘片高速旋转,使磁头到达数据的起始位置3、磁头沿磁道从磁盘读取或写入数据。当一次读取的数据量很少的时候,1、2步骤带来的开销是无法忽略的,这使得随机写相对于顺序写会有巨大的性能劣势。因为在顺序写的时候,1、2步骤只需要执行一次,剩下的全是数据传输所需要的固有开销;而每次随机写的时候,前两个步骤都需要执行,带来了极大的额外开销。
  • 其次再说一下页缓存:即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存。所以Kafka的数据并 不是实时的写入硬盘 ,它充分利用了现代操作系统 分页存储 来利用内存提高I/O效率。Memory Mapped Files也被翻译成 内存映射文件 ,在64位操作系统中一般可以表示20G的数据文件,它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候),也就是说,将复杂的IO操作交给了操作系统。

消费者(consumer)读取数据:
Kafka在消费数据的时候,为了提高读取速度,运用了零拷贝技术。

  • 零拷贝:考虑这样一种常用的情形:你需要将静态内容(类似图片、文件)展示给用户。那么这个情形就意味着你需要先将静态内容从磁盘中拷贝出来放到一个内存buf中,然后将这个buf通过socket传输给用户,进而用户或者静态内容的展示。这看起来再正常不过了,但是实际上这是很低效的流程,我们把上面的这种情形抽象成下面的过程:
    1.首先,调用read时,文件A拷贝到了kernel模式;
    2.之后,CPU控制将kernel模式数据copy到user模式下;
    3.调用write时,先将user模式下的内容copy到kernel模式下的socket的buffer中;
    4.最后将kernel模式下的socket buffer的数据copy到网卡设备中传送;
    幸运的是,你可以用一种叫做Zero-Copy的技术来去掉这些无谓的copy。应用程序用Zero-Copy来请求kernel直接把disk的data传输给socket,而不是通过应用程序传输。Zero-Copy大大提高了应用程序的性能,并且减少了kernel和user模式上下文的切换。