Kafka入门实战教程(5):吞吐量与可靠性的实践
1 提高Producer吞吐量的实践
在实际环境中,用户似乎总是愿意用较小的延时增加的代价,去换取 TPS 的显著提升。毕竟,从 2ms 到 10ms 的延时增加通常是可以忍受的。
事实上,Kafka Producer 就是采取了这样的设计思想。每当 producer 发布一个立即就发送 到 producer聚集一堆发布后批量发送,如下图所示:
我们可以在客户端做一些配置,来实现producer的高吞吐量,涉及到的一些重要配置如下:
批次大小,它和等待时间只要有一个满足就会发送,默认16K,可以修改为32K~512K。
等待时间,它和批次大小只要有一个满足就会发送,建议设置为5~100ms(根据你的场景来修改)。
压缩算法,使用压缩算法网络传递效率高,但也会相应耗费CPU,建议设置为LZ4或zstd。
缓冲区大小,默认1G,基本无需修改,最大可改为2GB。
下面的示例展示了基于Confluent.Kafka客户端组件如何对上面的配置项进行设置(均需要在Publish操作之前设置好),请注意查看带有注释的区域:
public async Task PublishAsync<T>(string topicName, T message) where T : class
{
var config = new ProducerConfig
{
BootstrapServers = KAFKA_SERVERS,
QueueBufferingMaxKbytes = 2097151, // 修改缓冲区最大为2GB,默认为1GB
CompressionType = CompressionType.Lz4, // 配置使用压缩算法LZ4,其他:gzip/snappy/zstd
BatchSize = 32768, // 修改批次大小为32K
LingerMs = 20 // 修改等待时间为20ms
}; using (var producer = new ProducerBuilder<string, string>(config).Build())
{
producer.Produce(topicName, new Message<string, string>
{
Key = Guid.NewGuid().ToString(),
Value = JsonConvert.SerializeObject(message)
}); ;
}
}
2 高可靠性消息的实践
在MQ中,一般存在两种情况的消息丢失:
producer端消息丢失
consuer端消息丢失
对于producer端消息丢失,一般会采用带回调函数的produce方法,且设置acks=all和设计一个较大的retry次数来避免消息丢失。
对于consumer端消息丢失,一般会采用关闭自动提交位移来避免消息丢失。
此外,要避免消息丢失,broker端也需要进行一些优化配置。
下面,我们就一起来看看。
Producer端
基于Confluent.Kafka的示例配置设置示例:重点关注注释部分
public async Task PublishAsync<T>(string topicName, T message) where T : class
{
var config = new ProducerConfig
{
BootstrapServers = KAFKA_SERVERS,
Acks = Acks.All, // 表明只有所有副本Broker都收到消息才算提交成功
MessageSendMaxRetries = 50, // 消息发送失败最大重试50次
......
}; using (var producer = new ProducerBuilder<string, string>(config).Build())
{
var numProduced = 0;
var key = Guid.NewGuid().ToString();
var value = JsonConvert.SerializeObject(message);
// 使用带回调函数的Produce方法
producer.Produce(topicName, new Message<string, string> { Key = key, Value = value },
(deliveryReport) =>
{
if (deliveryReport.Error.Code != ErrorCode.NoError)
{
// 发送失败
Console.WriteLine($"[Error] Failed to deliver message: {deliveryReport.Error.Reason}");
}
else
{
// 发送成功
Console.WriteLine($"[Info] Produced event to topic {topicName}: key = {key} value = {value}");
numProduced += 1;
}
}); // 等待所有回调函数执行完成,参数是超时时间,也就是最大的等待时间
var queueSize = producer.Flush(TimeSpan.FromSeconds(5));
if (queueSize > 0)
Console.WriteLine($"[Warn] Producer event queue has {queueSize} pending events on exit."); Console.WriteLine($"[Info] {numProduced} messages were produced to topic {topicName}");
} await Task.CompletedTask;
}
Consumer端
基于Confluent.Kafka的示例配置设置示例:重点关注注释部分
public async Task SubscribeAsync<T>(IEnumerable<string> topics, Action<T> messageFunc, CancellationToken cancellationToken = default) where T : class
{
var config = new ConsumerConfig
{
BootstrapServers = KAFKA_SERVERS,
.....
EnableAutoCommit = false, // 禁止AutoCommit
Acks = Acks.All, // 需要所有副本响应才算消费完成
......
}; using (var consumer = new ConsumerBuilder<Ignore, string>(config).Build())
{
consumer.Subscribe(topics);
try
{
while (true)
{
try
{
var cr = consumer.Consume(cancellationToken);
var message = JsonConvert.DeserializeObject<T>(cr.Message.Value);
if (message != null)
messageFunc(message);
consumer.Commit(cr); // 手动提交位移,会产生阻塞,影响吞吐量
Console.WriteLine($"[Info] Consumed record successfully! Received message: {message}");
}
catch (ConsumeException e)
{
Console.WriteLine($"[Error] Error occured in consuming: {e.Error.Reason}");
}
}
}
catch (OperationCanceledException)
{
// Ctrl+C Pressed
Console.WriteLine("[Info] Ctr+C pressed, now closing consumer.");
consumer.Close();
}
} await Task.CompletedTask;
}
Broker端
对于Broker端,可以修改以下三个配置以适应高可靠性的要求:
unclean.leader.election.enable = false
replication.factor >= 3
min.insync.replicas > 1
确保 replication.factor > min.insync.replicas
(1)设置 unclean.leader.election.enable = false
这是 Broker 端的参数,它控制的是哪些 Broker 有资格竞选分区的 Leader。如果一个 Broker 落后原先的 Leader 太多,那么它一旦成为新的 Leader,必然会造成消息的丢失。故一般都要将该参数设置成 false,即不允许这种情况的发生。
从Kafka 0.11版本开始,这个选项的默认值就变成了false。
(2)设置 replication.factor >= 3
这也是 Broker 端的参数(Topic参数)。其实这里想表述的是,最好将消息多保存几份,毕竟目前防止消息丢失的主要机制就是冗余。
(3)设置 min.insync.replicas > 1
这依然是 Broker 端参数(Topic参数),控制的是消息至少要被写入到多少个副本才算是“已提交”。设置成大于 1 可以提升消息持久性。在实际环境中千万不要使用默认值 1。
(4)确保 replication.factor > min.insync.replicas
如果两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了。我们不仅要改善消息的持久性,防止数据丢失,还要在不降低可用性的基础上完成。推荐设置成 replication.factor = min.insync.replicas + 1。
示例:设置replication.factor=3, min.insync.replicas=2
kafka-topics.sh --create --zookeeper zk-server-master:2181/kafka --replication-factor 3 --partitions 3 --topic testtopic--config min.insync.replicas=2
上述配置其实就是实现一个类似MongoDB副本集的WriteConcern=Major的效果。
3 总结
本文介绍了提高producer吞吐量 与 提高消息可靠性 的实践,重点介绍了在Confluent.Kafka组件下如何进行配置的代码实践,相信会对你有所帮助。
参考资料
极客时间,胡夕《Kafka核心技术与实战》
B站,尚硅谷《Kafka 3.x入门到精通教程》
Kafka入门实战教程(5):吞吐量与可靠性的实践的更多相关文章
- Kafka入门实战教程(7):Kafka Streams
1 关于流处理 流处理平台(Streaming Systems)是处理无限数据集(Unbounded Dataset)的数据处理引擎,而流处理是与批处理(Batch Processing)相对应的.所 ...
- 转 Kafka入门经典教程
Kafka入门经典教程 http://www.aboutyun.com/thread-12882-1-1.html 问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic. ...
- Kafka入门经典教程
本帖最后由 desehawk 于 2015-5-3 00:45 编辑问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程 ...
- Kafka入门经典教程【转】
问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有 ...
- [入门帮助] Kafka入门经典教程
问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有 ...
- ZooKeeper入门实战教程(一)-介绍与核心概念
1.ZooKeeper介绍与核心概念1.1 简介ZooKeeper最为主要的使用场景,是作为分布式系统的分布式协同服务.在学习zookeeper之前,先要对分布式系统的概念有所了解,否则你将完全不知道 ...
- 《OD大数据实战》Kafka入门实例
官网: 参考文档: Kafka入门经典教程 Kafka工作原理详解 一.安装zookeeper 1. 下载zookeeper-3.4.5-cdh5.3.6.tar.gz 下载地址为: http://a ...
- kafka实战教程(python操作kafka),kafka配置文件详解
kafka实战教程(python操作kafka),kafka配置文件详解 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是 ...
- Kafka入门教程(一)
转自:https://blog.csdn.net/yuan_xw/article/details/51210954 1 Kafka入门教程 1.1 消息队列(Message Queue) Messag ...
- Kafka入门教程(二)
转自:https://blog.csdn.net/yuan_xw/article/details/79188061 Kafka集群环境安装 相关下载 JDK要求1.8版本以上. JDK安装教程:htt ...
随机推荐
- 【Linux】5.8 Shell流程控制
Shell 流程控制 1. 判断语句 1.1 if判断 if else-if else 语法格式: if condition1 then command1 elif condition2 then c ...
- 【SpringMVC】视图和视图解析器
视图和视图解析器 Spring MVC如何解析视图 视图和视图解析器 请求处理方法执行完成后,最终返回一个 ModelAndView对象.对于那些返回 String,View 或 ModeMap 等类 ...
- AI团队比单打独斗强!CrewAI多智能体协作系统开发踩坑全解析
AI团队比单打独斗强!CrewAI多智能体协作系统开发踩坑全解析 阅读时间: 5分钟 | 字数: 1500+ "你是否曾为单个大模型难以解决复杂专业问题而苦恼?是否想过,如果能像组建专业团队 ...
- DIY记录之 USBasp
序 笔者在上网浏览时发现了这个项目[0].刚好另一个DIY会需要对Attiny85进行烧写,并且感觉自己做一个USBasp来干这个事比较有趣,于是就买材料打板子准备DIY一个USBasp.这篇随笔是用 ...
- java 限流
题记 在高并发的分布式系统中,我们都需要考虑接口并发量突增时造成的严重后果,后端服务的高压力严重甚至会导致系统宕机.为避免这种问题,我们都会为接口添加限流.降级.熔断等能力,从而使接口更为健壮. 限流 ...
- 科研新体验:刘同学深度试用ADTF软件反馈揭晓!
一.前言 作为一名高校的科研工作者,在高校的科研工作中,经常需要处理各种复杂的数据流,尤其是视频采集和处理的工作,对数据的实时性和精度要求非常高,我首次试用ADTF时,主要负责开发一个集成FFmpeg ...
- Argo CD
目录 一.什么是 Argo CD 二.为什么选择 Argo CD 三.Argo CD 架构 1.API服务器 2.存储库服务器 3.应用程序控制器 四.Argo CD 的使用 1.要求 2.安装 Ar ...
- 可轻便docker部署的密码保存系统:Vaultwarden
一.简介 Vaultwarden是著名的Bitwarden项目的一个分支,是一个社区驱动的项目,使用Rust语言编写.它是Bitwarden的轻量级自托管替代方案,完全兼容Bitwarden客户端协议 ...
- FastAPI与Tortoise-ORM开发的神奇之旅
title: FastAPI与Tortoise-ORM开发的神奇之旅 date: 2025/05/05 00:15:48 updated: 2025/05/05 00:15:48 author: cm ...
- 【经验】VMware|windows更新20H2版本后VMware虚拟机无法开启(禁用Device guard)
2021/04/27 针对 Windows 10 的功能更新, 版本 20H2. 出现如下报错. 解决方法参考官网:MSDN-<Manage Windows Defender Credentia ...