《深入理解kafka》对于实际问题的理解

Q1:消息可靠性(不重不漏)

[1.1 如何保证消息不丢](#1.1 如何保证消息不丢)

[1.2 如何保证消息不重](#1.2 如何保证消息不重)

Q2:积压/消费能力

[2.1 线上积压排查思路](#2.1 线上积压排查思路)

[2.2 增加消费能力](#2.2 增加消费能力)

Q1:消息可靠性(不重不漏)

理解可靠性前。介绍消息语义,即消息传递的标准

标准 丢失 重复 适用场景
At most once(至多一次) 会丢失 不会重复 高并发高吞吐,允许消息丢失,如日志收集
At least once(至少一次) 不会丢失 会重复
Exactly once(恰好一次) 不会丢失 不会重复

1.1 如何保证消息不丢

从各个层面分析

  • 参照:​《深入理解kafka-核心设计与实践原理》​第8.3章 + 自己理解
层面 事项
生产者(客户端) * 代码发送层面 * **①发送消息Api的三种模式:**发后即忘、同步和异步。发后即忘会丢失消息,后两者能知道是否发送成功 * **②补发消息机制:**客户端持久化消息,支持消息的补偿 * 配置层面 * **③生产者客户端参数(acks参数):**acks= -1最可靠,其余两种都可能会丢失消息 * **④重试参数(retries参数和retry.backoff.ms参数):**对于可重试的异常(如网络抖动),通过失败重试机制重发消息
Broker服务端 服务端需要注意的都是配置参数层面 * ①副本数(replication.factor参数) > 1 * 越多的副本数越能够保证数据的可靠性,但副本太多会影响性能。应对宕机风险,通常设置为3就能满足大多数场景 * ②ISR集合中的最小副本数(min.insync.replicas参数) >1 * 用于辅助配合acks=-1来使用:leader副本的消息流入速度很快,而follower副本的同步速度很慢。在某个临界点时所有的follower副本都被剔除出了ISR集合,那么ISR最终只剩一个leader副本,导致acks=-1演变为acks=1的情形 * 该值必须小于副本数,一个典型的配置是:replication.factor=3,min.insync.replicas=2 * **③是否允许从非ISR中选举新leader(unclean.leader.election.enable参数) = false:**默认为false,不允许 * 非ISR集合中,可能还未同步所有消息,设置成true会造成消息丢失 * 其他:log.flush.interval.messages和log.flush.interval.ms,是否开启同步刷盘(默认是不做控制而交由操作系统本身来进行处理) * 可能性分析:由于刷盘是操作系统控制,理论上讲会存在即使kafka写入成功,但由于机器宕机,操作系统未及时刷盘,丢失数据的风险 * 但同步刷盘非常损耗性能,改成每次提交时手动同步刷盘对性能影响太大。这里不建议修改此配置,因为发生可能性很小
消费者(客户端) **①自动提交(enable.auto.commit参数) = false:**默认为true,自动提交。不再介绍,见3.2.5节 * 自动提交会带来重复消费和消息丢失的问题:消费者还未执行完业务流程,异步线程已对服务端发起了提交 * 手动提交需遵守一个原则:如没有消费完,则不能提交

1.2 如何保证消息不重

消息重复无法避免,只能在消费者消费时过滤重复消息。可能的重复原因如下:

根因
生产者 业务方代码原因:对同一份消息内容发送了多次 ②网络问题:生产端发送消息后,服务端已经收到消息了,但是假如遇到网络问题,无法获得响应,生产端就无法判断该消息是否成功提交到了 Kafka,而我们一般会配置重试次数,但这样会引发生产端重新发送同一条消息,从而造成消息重复的发送
Broker服务端 服务端不会重复存储消息,如果有重复消息也应该是由生产端重复发送造成的
消费者 分区重分配引起 * 在客户端实例变化、分区扩容、集群切换等场景会涉及到分区重分配,由于新老客户端感知分配结果不及时,可能出现两台机器短时间消费同一个分区的场景,造成重复消费

备注:分区重分配,与再均衡(rebalance)的区别

  • 重分配:作用在broker层面,是broker与partition间的分配;通常是为了管理优化集群手动触发
  • 再平衡:作用在消费组层面(新增/下线消费者),Rebalance的目的是确保分区在consumer group成员之间平均分配,以便每个consumer都有分区去消费;通常是Kafka协调器自动触发的

处理思路:幂等

从对系统的影响结果来说:At least once + 幂等消费 = Exactly once。

  1. 利用数据库的唯一约束实现幂等

  2. 记录消费结果并检查操作

Q2:积压/消费能力

2.1 线上积压排查思路

是什么引起的积压:

  • 先止损,快速定位积压的原因

    • 上游生产流量突增

    • 上游流量没变

      • 不消费了:

        • 消费者是否下线了?

        • 某一个partition的offset卡住了?

      • 还在消费:消费能力下降?

2.2 增加消费能力

搞清原因:什么导致【消费速率 < 生产速率】

生产速率 可能原因 解决方案 备注
生产速率不高 自身业务消费链路长,导致消费慢 优化消费链路 绝大多数情况
生产速率高 ①消费者实例 < partition数量。一台机器消费多个partition的情况,并且机器负载较高 扩集群机器,一直到【消费者:partition=1:1】 影响可控
生产速率高 ②消费者实例:partition = 1:1,但消费速率仍小于生产速率 扩partition。但一未扩partition会增加服务端负载 影响可控
生产速率高 ③partition本身已很多,但生产速率实在太大 增加单partiton并行消费线程数目(这种方式不保证消费顺序!!!) * mafka和rocketmq支持,kafka与rabbitmq不支持 * 总体思路:滑动窗口 是不是该考虑架构与技术选型的问题了?
生产速率高 ④生产速率实在太大了 pushServer 是不是该考虑架构与技术选型的问题了?
相关推荐
WX187021128737 小时前
在分布式光伏电站如何进行电能质量的治理?
分布式
Stringzhua7 小时前
【SpringCloud】Kafka消息中间件
spring·spring cloud·kafka
不能再留遗憾了10 小时前
RabbitMQ 高级特性——消息分发
分布式·rabbitmq·ruby
茶馆大橘10 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
材料苦逼不会梦到计算机白富美13 小时前
golang分布式缓存项目 Day 1
分布式·缓存·golang
想进大厂的小王13 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
Java 第一深情13 小时前
高性能分布式缓存Redis-数据管理与性能提升之道
redis·分布式·缓存
杨荧14 小时前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
ZHOU西口14 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
zmd-zk15 小时前
kafka+zookeeper的搭建
大数据·分布式·zookeeper·中间件·kafka