You need to enable JavaScript to run this app.
导航

Kafka CPU 消耗场景分析

最近更新时间2023.12.14 20:42:06

首次发布时间2023.12.14 20:42:06

本文档主要介绍 Kafka 使用过程中可能产生 CPU 大量消耗的场景,并针对各个场景提供客户端使用策略相关的优化建议。

背景信息

基于产品定位与产品设计,Kafka 并非计算密集型产品,Kafka 实例的业务数据量主要体现在网络带宽占用与磁盘的吞吐,日常场景下无需关注 CPU 占用率。但是在实际生产环境中,往往存在多样化的使用场景,部分业务模型中 CPU 也会成为服务端的使用瓶颈。
目前对于服务端 CPU 消耗比较大的主要场景有请求速率过快、客户端消息格式低于服务端版本。

请求速率过快

Kafka 在客户端的设计实现中就已经考虑到请求速率过快的问题。

  • 对于消息发送,Kafka客户端的设计本身并不是同步消息发送的,业务在调用发送接口后,消息并不会直接发送到服务端,而是缓存在客户端内存中,发送的消息会在缓存中做消息聚合。之后由客户端后台会维护的一个异步发送线程来不断从内存缓存中读取数据,然后再将数据发送到服务端。

    说明

    因为 Kafka 是异步发送的方式,建议关注发送结果的回调函数。

  • 而对于消息消费,Kafka客户端使用了拉(pull)模式来实现,由客户端主动发起消息读取的请求。每次消息读取也是批量读取,之后将读取的结果缓存在本地内存中,之后业务调用接口从再缓存中读取数据。

发送和消费都已经使用了批量聚合方式,但是部分场景下也会存在过快的请求速率。原因在于 Kafka 本身默认的配置都为尽速处理,发送端尽可能快地发送,消费端尽可能快地消费。因而在用户业务量相对较大的场景下,默认的配置无法满足具体的业务请求。
通常造成请求过多的原因主要包括以下几种:

主要因素

说明

生产单个请求过小

同样发送 1MB 的数据,若每个请求只发送 1KB 的数据,则需要 1024 个请求,但是若每个请求发送 10KB 数据,则只需要发送 102 个请求即可。
以下参数可以用于生产客户端调优:

  • batch.size:控制每个分区在生产客户端做消息聚合的大小,默认为 16KB。若生产流量较高的情况下可以调整为较大值,例如 512KB。
  • linger.ms:控制每个分区做消息聚合的聚合时长,默认为 0ms。若生产者的写频率不是很快,单独调整 batch.size 效果可能效果并不明显,也需要配置修改此值进行调优,例如 50ms。
  • send.buffer.bytes:控制 TCP 发送缓冲区大小,默认为 128KB。在调整 batch.size 之后,为了在 TCP 缓存区中消息可以及时发送,可以适当调整,例如 1MB。

消费单次拉取消息过小

与生产消息类似,若每次消息拉取时拉取更多的消息,则对于相同的数据,可以使用更少的拉取请求则可以完成数据读。
消费客户端可以通过以下参数可以控制单次拉取的消息大小。

  • fetch.min.bytes:单次请求拉取的最小数据量,默认值为 0KB。若读取的消息不满足最小要求,则请求会在服务端等待数据满足最小要求或者一段时间(默认500ms)后再返回。因而在消费数据量较大的情况下,可以适当调整此值的大小,从而降低消费请求速率,例如 1MB。
  • receive.buffer.bytes:控制 TCP 接受缓冲区大小,默认为 64KB,若业务量较大的情况下,可以适当调整,例如 1MB。

消费位点提交频繁

消费进度通常都通过消费位点提交请求持久化到 kafka 服务端,因而消费位点提交过于频繁也会导致服务端 CPU 使用率增加。此处建议消费位点的提交按照一定的时间间隔设计,不建议使用消费消息数的方式进行提交设计,从而保证消费位点的提交不会因为业务量的增大而带来增长。

客户端过多

除了单个客户端请求过高之外,还存在一种场景,业务中使用了大量的客户端进行访问,从而导致即使单个客户端请求较少的情况下,也会使得总体的请求数过高。此种场景下,建议选用更大 CPU 的规格实例,或者对自身业务进行优化。

客户端消息版本过低

截止当前,Kafka 历史版本演进存在过两次消息格式的版本迭代,第一次为 0.10 版本,第二次为 0.11 版本。当前火山支持的版本,消息格式都为最新的版本,如果客户端支持的消息版本与服务端消息版本不一致,那么在服务端存储之前会转换为服务端本地的消息格式进行存储,而在消费时,又会将消息格式转换成消费者支持的格式。这个过程对于 CPU 的消耗相对更高。
对于这种情况,推荐的方式是更新客户端的版本,保证不会导致在生产与消费的过程中格式不一致从而导致产生消息转换。当前火山 Kafka 都支持 v2 版本的消息格式,推荐使用 2.2 以上版本的客户端。