# Kafka

## 概念

**消息**：Kafka 的数据单元，Kafka 不理解消息内容。\
**元数据（键）**：可用于控制写入不同的分区。\
**消息模式**：额外的接口定义消息内容。\
**主题**：不同的消息类型。\
**分区**：一个主题有多个分区，一个分区就是一个提交日志，消息以追加的方式写入分区，然后以 FIFO 的方式读取。所以无法在整个主题范围内保证顺序，但是可以在单个分区内保证顺序。\
**生产者**：创建消息。默认均匀发布到一个主题的不同分区，可通过消息键发送到指定分区。\
**消费者**：读取数据。可订阅一个或多个主题。通过偏移量来区分已经读过的数据。\
**消费者群组**：消费者群组包含多个消费者，群组保证每个分区只能被一个消费者使用。\
**偏移量**：一种元数据，递增的整数值。\
**broker**：一个 Kafka 进程实例。

## 发送消息 Batch 机制

客户端在发送消息给 kafka 服务端时，当有多个消息需要被发送到同一个分区时，生产者会把它们放在同一个批次里，一次通过网络把 Batch 发送过去。提升了吞吐量。

* batch.size：批次的大小。
* linger.ms：发送批次之前等待时间，若达到时间，批次就算没满，也会发送。

**问题**：若没做特殊处理，这些一个个 Batch 数据发送给服务端后，就需要 GC 来回收，这样就会带来较多的 Stop the world 时间，降低性能。

解决方案：**客户端缓冲池机制**。

客户端在开始时就申请一段内存，把这段内存划分成多块，每当需要创建一个 Batch 时就找缓冲池哪一块，Batch 用完后还回给缓冲池就行。所以这样就**避免了频繁的申请内存与 JVM GC**。

当缓冲池满了，无法申请 Batch 时，写入操作就会被阻塞，直到有空闲内存。

* <https://juejin.im/post/5cceec5c51882541914ade42>
