Kafka 调优

image.png

生产者

缓冲区大小与Sender线程发送包大小

从生产者架构图我们可以看出,有两个地方是比较重要且影响性能的:

  1. RecordAccumulator内存缓冲区;
  2. Sender线程的两个阈值;
  • batch.size:只有数据积累到 batch.size 之后,sender 才会发送数据,默认16kb。
  • linger.ms:如果数据迟迟未达到 batch.size sender 等待 linger.time 之后就会发送数据。
  • buffer.memory:RecordAccumulator 缓冲区大小 默认32M。

这两个区域参数需要根据发送消息的QPS、每条消息的占用空间的大小和Sender线程发送消息的速度进行容量预估,然后通过压测工具进行验证。

缓冲区域默认是32M,如果一条消息占用空间大小是512B,那么这个区域最大存放消息的数据就是32*1024*1024/512=65535条数据。
Sender线程一次发送数据量的大小,默认是16kB,16*1024/512=32,也就是说一次可以发送32条数据。那么65535条数据就需要发送2048次。

消息发送确认机制acks

生产者中还有一个比较重要的参数会影响性能acks(确认机制):

  • 1:当消息写到 leader 成功后向生产者返回 ack,如果在 follower 同步成功之前 leader 故障,那么将会丢失数据,默认是这个级别;
  • 0:不向生产者返回ack,这种情况下生产者延迟最低,broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据;
  • -1(all):当ISR中的所有副本都成功写入消息之后才像生产者返回ack。这种方式数据可靠,但是延迟最高;如果ISR副本同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复

重试机制(retries和retry.backoff.ms)

  • retries:配置生产者重试的次数,默认值为0,即在发生异常的时候不进行任何重试动作。
  • retry.backoff.ms:设定两次重试之间的时间间隔,避免无效的频繁重试,默认值为100。

消费者配置

fetch.min.bytes:

每次fetch请求时,server应该返回的最小字节数。如果没有足够的数据返回,请求会等待,直到足够的数据才会返回。

auto.commit.enable

如果为真,consumer所fetch的消息的offset将会自动的同步到zookeeper。这项提交的offset将在进程挂掉时,由新的consumer使用。

选择合适的分区数

在Kafka中,性能与分区数有着必然的关系,在设定分区数时一般也需要考虑性能的因素。但分区数越多吞吐量就越高吗?

分区是Kafka 中最小的并行操作单元,对生产者而言,每一个分区的数据写入是完全可以并行化的;对消费者而言,Kafka 只允许单个分区中的消息被一个消费者线程消费,一个消费组的消费并行度完全依赖于所消费的分区数。但是分区数不是越多越好,这需要进行压测,最后得出一个比较好的一个分区数。

分区太多会带来的问题:

  1. 分区数会占用文件描述符,而一个进程所能支配的文件描述符是有限的。
  2. 分区数的多少还会影响系统的可用性。由于kafka存在分区和副本机制 leader 副本对外提供服务,并且所有副本都采用自动话管理,所以当分区数量越多,那么自动化管理就会越多。
  3. 分区数越多也会让Kafka的正常启动和关闭的耗时变得越长。

在没有压测情况下建议将分区数设定为集群中broker的倍数。假定集群中有3个broker节点,可以设定分区数为3、6、9等,至于倍数的选定可以参考预估的吞吐量。但是还是建议进行压测,进而找到最优的分区数。

常见优化

提升吞吐量

image.png

保证低时延

image.png

保证高持久

image.png

参考

https://www.cnblogs.com/gxyandwmm/p/11420736.html