写点什么

kafka 原理深度剖析系列|调优策略

  • 2022 年 1 月 25 日
  • 本文字数:3323 字

    阅读完需:约 11 分钟

上一篇文章中,我们为大家讲解了 Kafka 的分区分配策略,StickyAssignor 分配策略、RoundRobinAssignor 分配策略、RangeAssignor 分配策略,详细内容参kafka原理深度剖析系列|分区分配策略,本片文章,我们来看看 Kafka 的调优策略都有哪些。


⼀般说到调优都离不开监控,kafka 本身没有提供很好的图形化监控系统,但是有很多第三⽅的 kafka 监

控⼯具都做的相对不错:


  • Burrow

  • Kafka Monitor

  • Kafka Offset Monitor

  • Kafka Eagle


在平时的开发中,开发者使⽤kafka 来发送数据已经⾮常熟悉,但是在使⽤的过程中,很多开发者并没有深⼊的探索 kafka 使⽤过程中的参数配置,带来的损失就是没有充分的发挥出 kfka 的优势,⽆法很好的满⾜业务场景。

生产者配置与说明

Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("buffer.memory", 67108864); props.put("batch.size", 131072); props.put("linger.ms", 100); props.put("max.request.size", 10485760); props.put("acks", "1"); props.put("retries", 10); props.put("retry.backoff.ms", 500); KafkaProducer<String, String> producer = new KafkaProducer<String, String> (props);
复制代码

buffer.memory

Kafka 的客户端发送数据到服务器,⼀般要经过缓冲,当你通过 KafkaProducer 发送出去的消息是先进⼊到客户端本地的内存缓冲⾥,然后把很多消息收集成⼀个⼀个的 Batch,再发送到 Broker 上去的。所以这个“buffer.memory”的本质就是⽤来约束 KafkaProducer 能够使⽤的内存缓冲的⼤⼩的,它的默认值是 32MB。既然了解了这个含义,试想⼀下,在⽣产项⽬⾥,这个参数应该怎么来设置呢?


可以先想⼀下,如果这个内存缓冲设置的过⼩的话,可能会导致⼀个什么问题?⾸先要明确⼀点,在内存缓冲⾥⼤量的消息会缓冲在⾥⾯,形成⼀个⼀个的 Batch,每个 Batch⾥包含多条消息。然后 KafkaProducer 的 Sender 线程会把多个 Batch 打包成⼀个 Request 发送到 Kafka 服务器上去。



如果要是内存设置的太⼩,可能导致⼀个问题,消息快速的写⼊内存缓冲⾥⾯,但是 Sender 线程来不及把 Request 发送到 Kafka 服务器。这样是不是会造成内存缓冲很快就被写满?⼀旦被写满,就会阻塞⽤户线程,不让继续往 Kafka 写消息了。


所以对于“buffer.memory”这个参数应该结合⾃⼰的实际情况来进⾏压测,需要测算⼀下在⽣产环境,你的⽤户线程会以每秒多少消息的频率来写⼊内存缓冲。假如说每秒 300 条消息,那么你就需要压测⼀下,假设内存缓冲就 32MB,每秒写 300 条消息到内存缓冲,是否会经常把内存缓冲写满?经过这样的压测,你可以调试出来⼀个合理的内存⼤⼩。

batch.size

batch.size 是 Batch 数据量⼤⼩,默认值是 16KB,⼀般可以尝试把这个参数调节⼤⼀些,可以利⽤⾃⼰的⽣产环境发消息的负载来测试⼀ 下。⽐如说发送消息的频率就是每秒 300 条,那么如果“batch.size”调节到了 32KB,或者 64KB,是否可以提升发送消息的整体吞吐量。理论上来说,提升 batch 的⼤⼩,可以允许更多的数据缓冲在⾥⾯, 那么⼀次 Request 发送出去的数据量就更多了,这样吞吐量可能会有所提升。但是也不能⽆限⼤,过于⼤了之后,数据缓冲在 Batch⾥发送出去,那么岂发送消息的延迟就会很⾼。


举个例子,⼀条消息进⼊了 Batch,但是要等待 5 秒钟 Batch 才凑满了 64KB,然后才发送出去。那这条消息的延迟就是 5 秒钟。所以需要在这⾥按照⽣产环境的发消息的速率,调节不同的 Batch⼤⼩⾃⼰测⼀下最终出去的吞吐量以及消息的延迟,设置⼀个最合理的参数。

linger.ms

要是⼀个 Batch 迟迟⽆法凑满,此时就需要引⼊另外⼀个参数了“linger.ms”。它的含义是,Batch 被创建之后,最多过多久,不管这个 Batch 有没有写满,都必须发送出去了。


举个例⼦,一个 batch.size 是 16kb,现在某个低峰时间段,发送消息很慢。这就导致可能 Batch 被创建之后,陆陆续续有消息进来,但是迟迟⽆法凑够 16KB,难道此时就⼀直等着吗?如果你现在设置“linger.ms”是 50ms,那么只要这个 Batch 从创建开始到现在已经过了 50ms 了,哪怕它还没满 16KB,也要发送出去了。所以“linger.ms”决定了你的消息⼀旦写⼊⼀个 Batch,最多等待这么多时间,他⼀定会跟着 Batch⼀起发送出去。避免⼀个 Batch 迟迟凑不满,导致消息⼀直积压 在内存⾥发送不出去的情况。


要配合 batch.size⼀起来设置。举个例⼦,⾸先假设一个 Batch 是 32KB,我们需要估算下,正常情况下,⼀般多久会凑够⼀个 Batch,⽐如可能 20ms 就会凑够⼀个 Batch。那么 linger.ms 就可以设置为 25ms,也就是说,⼤部分的 Batch 在 20ms 内都会凑满,但是你的 linger.ms 可以保 证,哪怕遇到低峰时期,20ms 凑不满⼀个 Batch,还是会在 25ms 之后强制 Batch 发送出去。


如果要是你把 linger.ms 设置的太⼩了,⽐如默认就是 0ms,或者你设置个 5ms,那可能导致你的 Batch 虽然设置了 32KB,但是经常是还没凑够 32KB 的数据,5ms 之后就直接强制 Batch 发送出去,这样会导致你的 Batch 形同虚设,⼀直凑不满数据。

max.request.size

最⼤请求大小 :max.request.size,这个参数决定了每次发送给 Kafka 服务器请求的最⼤数值,同时也会限制你⼀条消息的最⼤也不能超过这个参数设置的值,你可以根据⾃⼰的消息的⼤⼩来灵活的调整。举个例⼦,发送的消息都是⼤的报⽂消息,每条消息都是很多的数据,⼀条消息可能都要 20KB。此时你的 batch.size 是不是就需要调节⼤⼀些?


⽐如设置个 512KB?然后你的 buffer.memory 是不是要给的⼤⼀些?设置 128MB?只有这样,才能让你在⼤消息的场景下,还能使⽤Batch 打包多条消息的机制。此时 “max.request.size”可以适当调⼤⼀些,⽐如调节到 5MB。

retries 与 retries.backoff.ms

“retries”和“retries.backoff.ms”决定了重试机制,也就是如果⼀个请求失败了可以重试⼏次,每次重试

的间隔是多少毫秒。

确认机制:acks

此配置是表明当⼀次 produce 请求被认为完成时的确认值。特别是,多少个其他 brokers 必须已经提交了

数据到他们的 log 并且向它们的 leader 确认了这些信息。典型的值包括:


0: 表示 producer 从来不等待来⾃broker 的确认信息,这个选择提供了最⼩的时延但同时⻛险最⼤(因

为当 server 宕机时,数据将会丢失)。

1:表示获得 leader replica 已经接收了数据的确认信息。这个选择时延较⼩同时确保了 server 确认接收

成功。

-1:producer 会获得所有同步 replicas 都收到数据的确认。同时时延最⼤,然⽽,这种⽅式并没有完全

消除丢失消息的⻛险,因为同步 replicas 的数量可能是 1。如果你想确保某些 replicas 接收到数据,那么你 应该在 topic-level 设置中选项 min.insync.replicas 设置⼀下。

min.insync.replicas

当⽣产者设置应答为"all"(或“-1”)时,此配置指定了成功写⼊的副本应答的最⼩数。如果没满⾜此最⼩

数,则⽣产者将引发异常(NotEnoughReplicas 或 NotEnoughReplicasAfterAppend) min.insync.replicas 和 acks 强制更⼤的耐⽤性时。典型的情况是创建⼀个副本为 3 的 topic,将 min.insync.replicas 设置为 2,并设置 acks 为“all”。如果多数副本没有收到写⼊,这将确保⽣产者引发异常。

消费者端配置和说明

fetch.min.bytes:

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

auto.commit.enable

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



更多福利

云智慧已开源集轻量级、聚合型、智能运维为一体的综合运维管理平台 OMP(Operation Management Platform) ,具备 纳管、部署、监控、巡检、自愈、备份、恢复 等功能,可为用户提供便捷的运维能力和业务管理,在提高运维人员等工作效率的同时,极大提升了业务的连续性和安全性。点击下方地址链接,欢迎大家给 OMP 点赞送 star,了解更多相关内容~

 

GitHub 地址: https://github.com/CloudWise-OpenSource/OMP 

Gitee 地址:https://gitee.com/CloudWise/OMP

 

微信扫描识别下方二维码,备注【OMP】加入 AIOps 社区运维管理平台 OMP 开发者交流群,与 OMP 项目 PMC 当面交流,和更多行业大佬一起交流学习~



发布于: 刚刚阅读数: 2
用户头像

全栈智能业务运维服务商 2021.03.10 加入

我们秉承Make Digital Online的使命,致力于通过先进的产品技术,为企业数字化转型和提升IT运营效率持续赋能。 https://www.cloudwise.com/

评论

发布
暂无评论
kafka 原理深度剖析系列|调优策略