Kafka Note(三)高吞吐王牌杀手锏

(三)kafka高吞吐王牌杀手锏

A. 顺序读写

  • 影响因素

    • 机械硬盘的io有两个阶段,分别为寻址 & 写入。
    • 寻址:物理动作,通过旋转和磁臂找到对应扇区,其动作较慢,耗时是毫秒级。
    • 写入:数据的写入阶段很快,非优化重点方向。
  • 核心效果:producer倾倒消息时是不断追加到文件的形式,因此kafka利用追加写入完成磁盘顺序读写,减少磁盘磁头寻道时间,远快于随机读写。

  • 补充说明:linux io调度有4种方法

    • NOOP(先进先出的队列)
    • CFQ(默认方法,根据io请求的地址排序,但是这导致小的io动作如果地址靠后的话就需要一直等待)
    • DEADLINE(CFQ的升级版,设置了等待时间的上限)
    • ANTICIPATORY(每个io请求都等6ms,如果这个时间内收到了地址相近的操作就合并一起)

B. 零拷贝zero copy

  • 核心效果:基于linux的send file命令,减少内核态到用户态之间的拷贝。

  • 具体流程

    1. 在内核态kernel中操作,将数据从disk复制到memory buffer,在kafka的场景下,其实数据从disk走到了page cache;
    2. 从page cache中把数据传递到socket buffer,最后给到nic buffer发出去。
  • 优势:上述两步操作都在内核态kernel中完成,若没有send file机制数据需要从第一步的page cache拷贝到用户态的kafka应用中,然后再从kafka应用中拷贝到内核态的socket buffer中,多了两次拷贝动作。

C. 页缓存page cache

  • 核心效果:数据在内存memory中的读写速度高于在磁盘disk下的读写速度,而page cache就是利用内存空间来实现提速的。
  • 具体流程:结合上方的zero copy,kafka完成了数据传输的“空中接力”。
    1. 生产者将数据发送到broker;
    2. broker将数据先存至page cache,再刷入磁盘;
    3. 消费者此时若拉取数据,数据可基于send file,在broker上直接从page cache中到socket buffer,再从nic buffer送出;
    4. 消费者凭借zero copy,结合page cache的加速更快获得数据。
  • 注意点:kafka会用到大量memory作为page cache,所以linux的swap空间会被使用起来,一些不活跃的进程被放入了swap

D. 分区机制partition

1. 分区过多会破坏Kafka追加写

  • partition底层对应的是一个或多个segment文件,若分区过多会导致有大量segment文件。虽然每个文件单独看都是追加写的模式,但是系统宏观角度下会切换写入多个segment文件,这样寻址成本等于是随机io(rocketMQ对此作了优化,所有分区数据写入一个commitLog)。
  • 若kafka部署在云盘或者使用ssd就不用担心该问题,前者走带宽,后者不需要物理寻址。

2. Kafka数据存储结构

  • Topic & partition:Topic由大量partitions构成,利用分布式结构分散在不同broker节点上增加并行能力,而提升partition可以进一步利用并发能力,随着增加对应下有消费者数目,尽可能地提升吞吐量。

  • 存储的微观单位:每个partition有单独的目录,目录下又被具体分为多个segments,单个segment由一对文件——索引文件 & 数据文件。默认情况下segment的数据文件大小为log.segment.bytes=1073741824,即1gb。

    1. 索引文件:0000000.index,其名称为该段的起始索引号,总体采用是稀疏索引的方式。索引文件由message索引号(从1开始)和该message的末尾offset组成。

      Message index Message position annotation
      1 0 第一条空的
      3 4597 稀疏index,直接index=3
      6 9807
    2. 数据文件:0000000.log,保存上方索引文件对应的数据内容,由数据和position组成。

      message data Message position annotation
      Message1 data part 0 第一条空的
      Message2 data part 2039 数据文件不可能稀疏,完整记载末尾的offset是多少
      Message3 data part 4597 对应index=3的情况
      Message4 data part 6830
      Message5 data part 7912
      Message6 data part 9807 对应index=6的情况
  • 删除机制

    1. 周期检查:broker server周期性地检测和删除不符合保留条件的segments,具体周期根据配置的log.retention.check.interval.ms参数,默认为5分钟。
    2. 基于时间保留:基于配置的log.retention.ms | log.retention.minutes | log.retention.hours(若都配置了,优先级罗列的这个顺序逐级降低),默认168hours(7天)。非激活状态下的segment超过这个时长后,会被清理。
    3. 基于文件大小保留:基于log.retention.bytes的配置,目录下所有segments的数据文件大小若大于这个值,则删除最早的segment。

E. 其他手段

  • 批量发送:生产者客户端缓存消息后批量发送给broker,消费者也批量从broker拉取数据,减少网络上的io次数。
  • 网络瓶颈:kafka的核心性能瓶颈不是cpu、磁盘,而是网络带宽,需尽可能的压缩数据(下个主题对kafka的网络进行了阐述说明)。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容