Kafka原理总结

Kafka

  • 高吞吐
    Kafka常用于大数据场景,因为它对批量传输的场景做了优化,producer发出的数据需要成批一次性发给Consumer。
  • 分布式
    Broker多个副本保存多个partition,partition也有多个副本。
  • Pub/Sub
    意味着和大部分MQ中间件一样会有Producer、Consumer、Broker这几个组件。
  • Scala
    和Java有关系,编译器不同但是一般都使用hotspot虚拟机运行字节码。

概念

  • topic
    消息类别

  • partition
    topic的分区,一个topic可以有多个分区。
    每个partition有主备来实现高可用,

  • offset
    消息在日志中的位置,即partition中的偏移量,也是该消息的唯一序号。

  • Broker
    Kafka服务端,负责消息存储和转发

  • Producer
    消息生产者

  • Consumer
    消息消费者

  • Consumer Group
    消费者分组

  • Zookeeper
    保存集群中Broker、topic、Partition等的元数据。
    还负责Broker的故障发现、partition leader选举

整体架构

Kafka整体架构

数据存储

partition数据文件

partition存储数据,每条Message数据包含:offset、size、data这3个属性:

  • offset
    在partition文件中的偏移量,不过是逻辑上的偏移量而不是物理偏移量,因为每个topic都会包含多个partition,offset记录的是从第0个partition初始位置开始的偏移量。
  • size
    数据大小
  • data
    消息本身数据

partition高可用

partition有主从来实现高可用,每个topic的partition有N个副本,N

数据文件分段segment

partition物理上由多个segment文件组成,每个offset以该offset的初始偏移量命名,在查找某个offset的消息的时候,可以直接用二分查找来定位。
为什么要有segment?
分批存储,当segment中的数据都被消费后可以直接将文件删除(消息清理),如果只存partition的话文件只会越来越大。

数据文件索引

分段数据只能按offset查询数据,必须要建立索引,索引文件名和数据文件的名字是一样的,只是文件扩展名为.index。
index文件不是给每条数据建立索引,而是每隔一定字节(每隔6个offset)的数据建立一条索引,好处是占用的空间少,可以尽可能将索引文件保存到内存中;缺点是没法一次性定位到数据所处的位置,需要在小范围内做一次顺序扫描。
index文件中存储的数据格式为:<offset, position>
offset是消息的标识,position表示消息具体存储位置。

需要注意的是Kafka不支持按tag过滤,Kafka不适合用于一些复杂的业务场景,比如订单topic可能会分食品订单(tag=food)和服装订单(tag=cloth),有一个索引服务会订阅该订单topic建索引,后来来了个下游服务只对食品(food)感兴趣,就没法使用Kafka来实现了。

Kafka如果找到一条数据

  1. 先拿到offset
  2. 二分查找找segment
  3. 从segment找消息
    将offset转换为物理偏移量。

Kafka读写速度为什么快?

  • 顺序写
    每个新消息写入到partition、segment的末尾
  • 二分查找
    通过二分查找找数据对应的segment文件,在文件中利用offset定位数据实际存储的位置。

消息发送

路由

如上所述,topic由多个partition组成,partition均分在不同broker上,多个partition通过Producer端的路由来均衡负载,提高整体吞吐量。
路由方式可以是:

  • 随机
  • hash

批量发送

批量发送是提高消息吞吐量的最重要方式。
Producer端在内存中合并多条消息后,以一次请求的方式发送这批数据。
优点是减少IO次数,提高吞吐量,缺点是减小了消息的实时性。