交易平台网站开发教程百度云,做文案的网站有些什么软件,网页设计素材的制作与收集,网页设计师行业分析#x1f44f;大家好#xff01;我是和风coding#xff0c;希望我的文章能给你带来帮助#xff01; #x1f525;如果感觉博主的文章还不错的话#xff0c;请#x1f44d;三连支持#x1f44d;一下博主哦 #x1f4dd;点击 我的主页 还可以看到和风的其他内容噢#x… 大家好我是和风coding希望我的文章能给你带来帮助 如果感觉博主的文章还不错的话请三连支持一下博主哦 点击 我的主页 还可以看到和风的其他内容噢更多内容等你来探索 欢迎参观我的个人网站Gentlewind 文章目录 kafka 的架构消息语义传递ProducerBrokerConsumer kafka 的架构
kafka 的架构非常简洁主要是分布式架构由 Producer、Broker、Consumer 组成。
所以分析丢失的场景也会由这三部分来进行。
从 Kafka 整体架构图我们可以得出有三次消息传递的过程
1Producer 端发送消息给 Broker 端。
2Broker 将消息进行同步并持久化数据。
3Consumer 端从 Broker 将消息拉取并进行消费。
消息语义传递
首先我们先了解一下保证消息传递的一个通信模型消息语义传递
他有三个类型
At Most Once最多一次消息在传递过程中最多被传递一次。也就是说消息可能会丢失但不会重复传递At Least Once至少一次消息在传递中至少传递一次。也就是消息不会丢失但可能重复传递Exactly Once恰好一次也就是精确的传递一次。既不丢失也不重复传递
我们需要**根据具体的场景选择需要的传递类型。**比如对消息丢失不能忍受但是可以接收消息重复传递就可以选择第二种类型。
然后再根据需求来对 kafka 进行相应的配置。就类似于 CAP 理论这是一个取舍问题。
Producer
Producer 端发送消息到 Broker 端消息丢失的情况可能会有
网络波动导致消息没有发送到 Broker发送途中 Broker 宕机了消息太大超过了 Broker 的容量被拒收了
总结丢失的原因就是消息根本没有发送到 broker 端
拓展Producer 端为了提升发送效率减少IO操作发送数据的时候是将多个请求合并成一个个 RecordBatch并将其封装转换成 Request 请求「异步」将数据发送出去也可以按时间间隔方式达到时间间隔自动发送
解决方案
ACK 机制
可以通过配置 ack 来对消息进行确认进而保证消息不丢失。
具体 ack 的配置为
acks 0不进行确认也就是实现第一种类型acks 1消息发送到 broker 的分区后进行一次 ack 确认确认接收成功后就完成了。但是它只保证了发送消息到主分区。如果从分区还没有同步完数据而主分区宕掉了就会造成丢数据。acks all对所有的主从分区进行 ack 确认都成功接收消息才完成。这样的可靠性最高但是相应的吞吐率也会更低。
其实就是同步的方式Producer要保证消息到达服务器就需要使用到消息确认机制也就是说必须要确保消息投递到服务端并且得到投递成功的响应确认服务器已接收才会继续往下执行。
Broker
kafka 中broker 接收到消息会先存放在 Pagecache 缓存中然后通过批量异步刷盘的策略来对数据进行同步和持久化。
Broker 将消息进行同步并持久化数据。消息丢失的情况有
当刷盘之前 broker 宕掉了然后推举出了一个落后数据的从分区。那么之前的数据就丢失了
解决方案
同步刷盘可以通过一些配置实现同步刷盘可以保证消息不丢失这样就算失败也可以进行及时补偿。
# 当达到下面的消息数量时会将数据flush到日志文件中。默认10000
#log.flush.interval.messages10000
# 当达到下面的时间(ms)时执行一次强制的flush操作。interval.ms和interval.messages无论哪个达到都会flush。默认3000ms
#log.flush.interval.ms1000
# 检查是否需要将日志flush的时间间隔
log.flush.scheduler.interval.ms 3000
同样可以达到同步刷盘的效果。
kafka 默认通过「**多 Partition 分区多 Replica副本机制」**已经可以最大限度的保证数据不丢失如果数据已经写入 PageCache 中但是还没来得及刷写到磁盘此时如果所在 Broker 突然宕机挂掉或者停电极端情况还是会造成数据丢失。
Consumer
Consumer 消费消息有两个步骤
从 broker 中拉取消息处理消息然后标记消息已经消费并提交 offset 记录消息位移记录下次继续消费的时候会接着上次的offset进行消费。
那么 Consumer 端从Broker 将消息拉取并进行消费可能丢失的场景有 开启了自动提交如果开启了自动提交那么系统会自动进行提交offset。可能会引起并未消费掉就提交了offset.引起数据的丢失。 并且自动提交也分两种情况 拉取消息后「先提交 Offset后处理消息」如果此时处理消息的时候异常宕机由于 Offset 已经提交了, 待 Consumer 重启后会从之前已提交的 Offset 下一个位置重新开始消费 之前未处理完成消息不会被再次处理对于该 Consumer 来说消息就丢失了。 拉取消息后「先处理消息在进行提交 Offset」 如果此时在提交之前发生异常宕机由于没有提交成功 Offset 待下次 Consumer 重启后还会从上次的 Offset 重新拉取消息不会出现消息丢失的情况 但是会出现重复消费的情况这里只能业务自己保证幂等性。
解决方案
设置参数enable.auto.commit false, 采用手动提交位移的方式。这样如果消费失败的情况下我们可以不断地进行重试。所以消费端不要设置自动提交一定设置为手动提交才能保证消息不丢失。而幂等的问题可以在业务逻辑中进行判断。