> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kafka 客户端配置调优

> AutoMQ 通过云原生对象存储提供高吞吐性能且不收费的分区管理。优化 Kafka 客户端性能并确保消息可靠性与消费效率，提升成本效益。

## 资源分配管理

### 建议 1：  合理设置 Topic 分区数，避免吞吐瓶颈以及浪费

Kafka Topic 分区数影响了 Topic 能够支持的生产和消费吞吐，在保证顺序的前提下，相同分区 Key 的消息发送到同一个分区，并且 Kafka 每个分区只能被一个消费者处理。

AutoMQ 基于对象存储构建，相比于 Apache Kafka 本地文件的架构，相同的集群规模下可以支持数十倍的分区性能。同时 AutoMQ 对分区不收费。

使用 AutoMQ 分配分区时，无需为成本考虑，只需要按照业务预估的分区吞吐性能评估合适的分区数（**AutoMQ 单个分区写入吞吐上限为 4MB/s** ），避免后期业务上量再扩展分区。分区数也无需和节点数量的倍数关联，AutoMQ 会自动实现分区的均衡。

<Tip>
  **举例：**

  某应用预估未来 1年内 Topic 数据写入吞吐大概是 100MB/s，同时下游消费者单个消费者每秒最多只能处理 2MB 的数据。

  则分配分区时需要考虑：

  基于生产者视角，需要 100MB/s ÷ 4MB/s = 25 个分区。

  基于消费者视角，需要 100MB/s ÷ 2MB/s = 50 个消费者，50 个消费者至少需要 50 个分区。

  因此，需要分配至少 50 个分区才可以满足应用的需求。
</Tip>

### 建议 2：  平台类应用场景，建议开启 ACL，实现上下游访问强管控，便于后期梳理链路拓扑

平台类场景，例如实时计算平台，使用 Kafka 时建议开启 ACL 实现资源细粒度管控。开启资源管控后Kafka 客户端必须进行身份校验才能访问特定的 Topic、Group。这样做有如下好处：

* 避免业务方随意创建新的 Topic 等资源，造成资源滥用，无法治理。

* 可以规避不同业务方混用 Consumer Group 造成订阅混乱，影响消费负载均衡。

* 根据 Topic、Consumer Group 就可以找出相关的订阅方和上下游业务组，方便进行业务治理。

## 生产者应用

### 建议 1：客户端小于 2.1 版本 Kafka Producer 建议设置重试次数

生产者应用需要检查 SDK 版本，如果当前版本小于 2.1，则需要手工设置重试次数，确保消息发送失败时可以自动重试，避免因服务端运维、自动分区迁移等场景造成失败。

重试参数设置可以参考如下信息：

```properties theme={null}

//最大重试次数
retries=Integer.MAX_VALUE 

//初始退避延迟时间。
retry.backoff.ms=100

//最大退避延迟时间。
retry.backoff.max.ms=1000

//每次发送请求的 RPC 超时时间
request.timeout.ms =30000

//整个发送调用整体超时时间，超过这个时间后即不再重试，返回调用侧失败异常。
delivery.timeout.ms=120000

```

### 建议 2： 优化 Producer 攒批参数，避免碎请求消耗过多 QPS

Kafka 是面向高吞吐场景设计的流存储系统，Kafka 最典型的使用场景是通过批处理提升数据收发过程的效率和吞吐。在 Producer 发送消息过程中需要合理设置攒批参数，避免出现以下情况：

* **避免每次请求只发送一条消息：** 生产者每次只发送一条消息会造成大量的 Produce 请求，消耗服务端 CPU，造成集群性能下降。

* **避免设置过长的攒批等待时间：** 生产者在设置批量参数时需要设置合理的等待时长，避免因小流量场景下一直无法攒批完成，造成发送消息延迟。

具体设置攒批的参数参考下方：

```properties theme={null}

//批量大小，一次性最多积累128KB 的数据。
batch.size=131072
//攒批时间，对于生产者，如果在指定的时间内没有达到攒批的上限，也会触发发送，这个时间代表了发送的最大延迟。
linger.ms=10

```

### 建议 3：设置 ack=all，确保消息持久化成功后再响应

生产者可以通过调整 ack 参数来在数据持久化和发送延迟之间均衡：

* ack=all（默认值）：服务端会在数据持久化到云存储后再响应给客户端。服务端宕机时，已响应成功的消息不会丢失。

* ack=1：AutoMQ 服务端和 Apache Kafka 保持一致，消息被接收到内存中后就立刻响应给客户端。服务端宕机时，未持久化的消息会丢失。

建议生产者维持默认配置 ack=all 保障数据的可靠性。

<Tip>
  AutoMQ 基于对象存储实现消息的持久性和可靠保存，服务端不会产生 ISR 副本复制。设置 ACK=ALL 的处理流量相当于写一份数据（同步持久化）。
</Tip>

## 消费者应用

### 建议 1：  注意 Assign 模式消费者，建议升级到 3.2 及以上版本，确保消费位点提交成功率

Kafka Consumer 应用在消费消息时，如果使用了 Assign 模式，即自行分配分区负载均衡的模式，需要确保 SDK 版本升级到 3.2 及以上版本。因为早期版本在 Assign 模式下会存提交消费位点的缺陷，导致消费者位点无法及时提交和更新。详细的缺陷记录参考[ Kafka Issue KAFKA-13563](https://issues.apache.org/jira/browse/KAFKA-13563)。

### 建议 2：合理控制 Consumer 心跳超时时间以及单次 poll 消息数量，避免频繁 Rebalance

Kafka Consumer 之间通过相同的 Group Id 进行分组和负载均衡，如果单个消费者出现了心跳超时，则会被驱逐出消费者分组，剩余的消费者会重新进行 Rebalance，分配分区。

在生产场景下，应该避免程序参数错误导致非预期的心跳超时和 Rebalance，否则会导致消费者分组一直变化无法消费消息。

**触发非预期 Rebalance 的原因：**

* v0.10.2之前版本的客户端：Consumer 没有独立线程维持心跳，而是把心跳维持与 poll 接口耦合在一起。其结果就是，如果用户消费出现卡顿，就会导致 Consumer 心跳超时，引发Rebalance。

* v0.10.2及之后版本的客户端：如果消费时间过慢，超过一定时间（max.poll.interval.ms设置的值，默认5分钟）未进行poll拉取消息，则会导致客户端主动离开队列，而引发Rebalance。

<Tip>
  **优化建议：**

  将客户端升级至0.10.2以上版本。

  参考以下说明调整参数值：

  尽量提高客户端的消费速度，避免卡顿。

  尽量避免一个 Group 订阅大量 Topic 的情况，做到专属 Group 订阅专属 Topic。
</Tip>

### 建议 3：生产场景建议提交消费位点，但不要高频率提交位点

使用 Kafka 消费消息时，无论使用普通的 Kafka Consumer SDK，还是使用 Flink Connector 等框架，都建议提交消费位点，这样可以观测消费堆积，避免风险。

提交消费位点有两种方式，一种是自动提交，一种是手动提交。控制的参数是：

* **enable.auto.commit** ：是否采用自动提交位点机制。默认值为true，表示默认采用自动提交机制。

* **auto.commit.interval.ms** ： 自动提交位点时间间隔。默认值为1000，即1s。

这两个参数组合的结果就是，每次poll数据前会先检查上次提交位点的时间，如果距离当前时间已经超过参数**auto.commit.interval.ms** 规定的时长，则客户端会启动位点提交动作。

因此，如果将**enable.auto.commit** 设置为true，则需要在每次poll数据时，确保前一次poll出来的数据已经消费完毕，否则可能导致位点跳跃。

如果想自己控制位点提交，请把**enable.auto.commit** 设为false，并调用commit(offsets)函数自行控制位点提交。

<Tip>
  生产场景下，建议一定要提交位点，但不要高频率的提交消费位点。否则会导致处理消费位点的 Compact Topic 分区出现请求热点。

  生产场景下建议根据需求，一般 5-10 秒定时或者手工提交即可，不需要每次消费消息都提交位点。
</Tip>

### 建议 4：生产场景避免消费阻塞导致堆积

Kafka 消费者按分区顺序处理消息，如果某条消息因业务逻辑导致消费阻塞，会影响当前分区后续消息的消费。因此生产环境中应确保消费逻辑处理不会永久阻塞。

如果出现非预期的阻塞情况，建议按以下流程处理：

* **判断是否可以跳过：** 如果可以跳过该异常消息，则可以先停止消费者，前往 AutoMQ 控制台重置消费位点到下一条消息，实现跳过处理。

* **判断不可跳过：** 修复消费逻辑，处理该异常消息。

## Flink 任务

### 建议 1：升级 Flink Connector 版本到 1.17.2 及以上，确保消费位点提交成功率

使用 Flink Connector 消费 Kafka 消息时，需要注意 Flink Connector 版本，建议升级到 1.17.2 及以上版本。因为早期的 Flink Connector 版本依赖了更早版本的 Kafka SDK，这些版本在提交消费位点时如果遇到失败则无法重试，这会导致 Flink 任务的 Consumer Group 在 Kafka 产品里无法准确观测堆积数指标。详细的缺陷记录参考[ Kafka Issue KAFKA-13563](https://issues.apache.org/jira/browse/KAFKA-13563)。
