【Kafka】3.纯原创,消息的发送/存储/消费流程综述

写在前面

本文为Kafka系列文章第三篇,全文可见:

  • 【Kafka】1.特性与零拷贝
  • 【Kafka】2.纯原创,一张图洞悉Kafka集群
  • 【Kafka】3.纯原创,消息的发送/存储/消费流程综述
  • 【Kafka】4.高可用及Failover流程

昨天写了一篇分享GRPC框架的博客竟然被jianshu给封了,也不知道这么纯粹的技术文章是哪里违反规定了 。Anyway,我已经申诉了 ,如果还是不行的话就换个平台继续写吧。

今天来讲讲Kafka的一些知识 ,关于Kafka我们都知道是消息队列组件,但是在全网搜了半天也没有一篇文章系统地来讲讲Kafka的消息处理的完整流程,信息显得太零碎了,所以我就动手总结了一下Kafka中消息的发送、存储和消费的完整流程。其中的流程图全部都是手画的,麻烦转载的时候至少跟我说一声哈。

Producer - 消息写入

kafka消息写入

消息写入-重点逻辑

  1. 幂等性发送:每个消息都在producer内根据topic,partition编号,对应leader通过校验编号实现有序接收和消息幂等
  2. 发送端的ACK配置:默认不等待,对于重要消息可以配置1或者2等待Leader及ISR的ACK消息
  3. ISR (in-sync replica set):
  • leader在ZK中 (/brokers//
  • 如果follower超过阈值时间 (replica.lag.time.max.ms,默认10s)未向leader拉取数据则会被剔出ISR。
  • 可配置ISR最低值限制-min.insync.replicas,小于该数据则当前Partition不可用(无法写入数据)

Kafka集群-消息存储

kafka消息存储

消息是全量存储的但是会定期淘汰:

  • 最大储量log.retention.bytes
  • 最大保留时间log.retention.hours (小时)
文件存储结构
  1. 每个partition的表现为一个文件夹
  2. partition文件夹内部按照offset分segment,比如10000-19999,20000-29999
    每个segment分为.log文件 (存储消息内容)和.index文件 (存储每个offset在log文件中位置/偏移量)
查找消息的时间复杂度

基本为稳定不变 —— O(1)+O(log(segment数量))+O(log(segment内行数))

  1. 根据partition,拼出文件名找到对应的文件夹:O(1)
  2. 文件夹内使用二分法找到这一offset所在的segment:O (log (segment_num))
    segment数量不会很大,取决于最大储量/segment_size,比如就是45G/5G=9个文件,所以近似为常量
  3. 在segment.index文件内部,同样通过二分法找到这一offset所在的行,即可找到它在.log文件中的偏移量:O (log (lines_num))
    lines_num最大值可配置,所以是常量

Consumer-消息消费

kafka消息消费流程

消息消费-重点逻辑

  1. Rebalance:
    触发条件:Partition或ConsumerGroup内的Consumer数量发生变化
    分配逻辑:range-先均分,除不尽的部分按照字典序从前到后分配,所以4个partition分给3个consumer为:2 1 1

  2. Offset维护逻辑:
    ConsumerGroup中的每个Partition的offset维护在_consumer_offset这个topic中
    该Topic的每个Partition维护固定的ConsumerGroup中的所有数据(一对多)
    提交Offset时是作为Producer向该Topic发送消息

  3. High Watermark:为leader+ISR中的最大offset的最小值,用于确保故障转移时多副本之间的数据一致性
    HW由Leader维护和更新,Consumer最大可拉取到HW,其后内容不可见
    故障转移时,Leader+所有的Follower会舍弃HW之后的内容,所有消息从HW重新开始累加

结尾

为了避免jianshu说我违规,参考链接暂时就不贴了。

你可能感兴趣的:(【Kafka】3.纯原创,消息的发送/存储/消费流程综述)