Kafka高吞吐的实现

Kafka高吞吐的实现

[TOC]

顺序读写

读取时间

  • 寻道时间,表示磁头在不同磁道之间移动的时间。
  • 旋转延迟,表示在磁道找到时,中轴带动盘面旋转到合适的扇区开头处。
  • 传输时间,表示盘面继续转动,实际读取数据的时间。
  • 顺序读写,磁盘会预读,预读即在读取的起始地址连续读取多个页面,主要时间花费在了传输时间,而这个时间两种读写可以认为是一样的。
  • 随机读写,因为数据没有在一起,将预读浪费掉了。需要多次寻道和旋转延迟。而这个时间可能是传输时间的许多倍。

​ kafka的消息是不断追加到文件中的,这个特性使kafka可以充分利用磁盘的顺序读写性能

​ 顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写

​ Kafka官方给出了测试数据(Raid-5,7200rpm):

​ 顺序 I/O: 600MB/s

​ 随机 I/O: 100KB/s

​ 读写一个文件之前,得一层层目录找到这个文件,以及做一堆属性、权限之类的检查。写新文件时还要加上寻找磁盘可用空间的耗时。对于小文件,这些时间消耗的占比就非常大了。

零拷贝

零拷贝就是一种避免 CPU 将数据从一块存储拷贝到另外一块存储的技术。

传统的数据复制:
磁盘文件->内核空间读取缓冲区->用户缓冲区(应用程序上下文)->socket缓冲区->网卡接口->消费者进程

零拷贝:
磁盘文件->内核空间读取缓冲区->网卡接口->消费者进程

直接略过用户缓冲区

分区

​ 并发读写,加快读写速度;多分区的存储,利于数据的均衡;

​ 在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,partiton序号从0开始,序号最大值为partitions数量减1。

broker–>topic–>partition–>segment file

segment file:分为index索引文件和log数据文件,分别以后缀”.index”和“.log”结尾。

文件中存放的是二进制流信息。

根据Offset如何快速定位到读取的信息:

索引文件和数据文件的文件名:00000000…..9999.index 存放,可通过二分法查找到文件

文件内部格式:
offset:123 postition:2898

文件可通过postition随机读取。

批量发送

Kafka允许进行批量发送消息,先将消息缓存在内存中,然后一次请求批量发送出去。比如可以指定缓存的消息达到某个量的时候就发出去,或者缓存了固定的时间后就发送出去。

如100条消息就发送,或者每5秒发送一次这种策略将大大减少服务端的I/O次数

数据压缩

​ 每个消息都压缩,但是压缩率相对很低。KAFKA使用了批量压缩,多个消息一起压缩。 降低网络带宽。
KAFKA允许使用递归的消息集合,批量的消息可以通过压缩的形式传输并且在日志中也可以保持压缩格式,直到被消费者解压缩。

​ KAFKA支持Gzip和Snappy压缩协议。

Consumer的负载均衡

​ 当一个 group 中,有 consumer 加入或者离开的时候,会触发 partitions 均衡,均衡的最终目的:提升 topic 的并发消费能力