头图

为什么这么快

上篇 文章提到了kafka的结构,其中有3点有助于提高它的吞吐量。

  1. partition并行处理
    多个partition承载一个topic的消息存储和传输,增加partition的数量能有效增加吞吐量。
  2. 写消息:消息存储采用顺序写的方式
    kafka消息存储在log文件中,文件采用顺序写的方式写入消息。由于磁盘结构,顺序写要比随机写快不少。
补充:
写消息还有一点优化,生产者向broker发送消息过程会先向Page Cache里写入,再异步刷盘到log文件。
为防止消息丢失,可以采用replication备份的方式。
  1. 读消息:文件命名和稀疏索引
    两者保证了消息的快速定位,加速消息消费。

除了以上内容,还有一个重要因素:

  1. 零拷贝技术

broker向消费者传递数据过程,按传统的做法会经历如下步骤:

image.png
应用程序发起读数据请求,磁盘数据经read buffer进入应用层buffer;再由应用层buffer进入socket buffer,通过网卡进行网络传输。

一份数据未做任何改变的前提下,经历了数次拷贝,期间还涉及用户态和内核态间的转换,这显然是一种浪费。

image.png
kafka利用DMA技术,实现了零拷贝。

DMA可以用在显卡、声卡等很多硬件上,这里主要用到了网卡的DMA

通过操作系统层面的sendfile函数,数据将简历read buffer到网卡的映射,然后直接发送出去。(要保证数据未做任何改变
而java的transferTo方法底层基于操作系统的sendfile实现。

升级后的方式不再需要用户态和内核态之间的切换,同时也免去了多次拷贝。

  1. 其它
    当然,kafka支持的批量消息和消息压缩都是其快的原因

主从同步机制

我们知道replication是partition的副本,而ISR就是master(partition所在broker)动态维护的一个集合,用来记录有效的replication副本。

先看下如下几个概念:

  • AR(Assigned Repllicas)一个partition的所有副本(就是replica,不区分leader或follower)
  • ISR(In-Sync Replicas)能够和 leader 保持同步的 follower + leader本身 组成的集合。
  • OSR(Out-Sync Relipcas)不能和 leader 保持同步的 follower 集合
  • 公式:AR = ISR + OSR

kafka会保证ISR集合中记录的副本会同步消息。

有关同步的配置如下:

# 默认10000 即 10秒
replica.lag.time.max.ms

这个配置的意思是10秒内达成完全同步的副本,会记录在ISR集合中;未完全同步则移出集合。

好,我们来看看完全同步的意思。在这之前先引出两个概念:

image.png

  • LEO(last end offset)
    一个partition中,最新消息的下一个offset
  • HW(high watermark)
    partition的所有replication中同步的最小offset。

图中的例子:
假如partition有8条消息(0-7),LEO为8;
这个partition有3个replication,其中的两个partition已经将8条消息同步了;
最后一个replication只同步了5条消息(0-4),那么HW会标记为5。
此时消息0-4对外可见(consumer可以消费),5-7不可见。

同时,10秒内此replication不能将5-7消息同步,它将被移出ISR

当replication将partition的LEO之前的日志全部同步时,则认为该replication已经追赶上partion,也就是完全同步

附录

P6-P7知识合辑


青鱼
268 声望25 粉丝

山就在那里,每走一步就近一些