无锡建网站企业,太原市建设工程交易中心网站,能自己做头像的网站,企业公司网站管理系统在 Kafka 的整个架构中可以总结出消息有三次传递的过程#xff1a;
Producer 端发送消息给 Broker 端Broker 将消息进行并持久化数据Consumer 端从 Broker 将消息拉取并进行消费
在以上这三步中每一步都可能会出现丢失数据的情况#xff0c; 那么 Kafka 到底在什么情况下才…在 Kafka 的整个架构中可以总结出消息有三次传递的过程
Producer 端发送消息给 Broker 端Broker 将消息进行并持久化数据Consumer 端从 Broker 将消息拉取并进行消费
在以上这三步中每一步都可能会出现丢失数据的情况 那么 Kafka 到底在什么情况下才能保证消息不丢失呢 Producer 端丢失
Producer 端为了提升发送效率减少 IO 操作发送消息的时候是将多个请求异步发送出去所以 Producer 端消息丢失更多是因为消息根本就没有发送到 Broker 端。
导致 Producer 端没有发送消息成功的有以下原因
网络原因由于网络抖动导致数据没发到 Broker 端数据原因消息体太大超出 Broker 承受范围导致 Broker 拒收消息
解决方案
Producer 端数据丢失是因为通过异步的方式进行发送的所以如果此时使用发后即焚的方式发送即调用 Producer.send(msg) 会立即返回由于没有回调可能因网络原因导致 Broker 并没有收到消息此时就丢失了。
因此可以从以下几方面进行解决 Producer 端消息丢失问题
使用带回调通知函数的方法进行发送消息ACK 确认机制重试次数
Producer 端通过 ACK 配置来确认消息是否生产成功配置参数如下
0由于发送后就自认为发送成功这时如果发生网络抖动会造成数据丢失1消息发送 Leader 分区并接收成功就表示发送成功只要 Leader 分区不挂掉就可以保证数据不丢数据但是如果 Leader 分区挂掉了Follower 分区还未同步完数据且没有 ACK这时就会丢数据-1 或者 all 消息发送需要等待 ISR 中 Leader 分区和所有的 Follower 分区都确认收到消息才算发送成功, 可靠性最高但也不能保证不丢数据比如当 ISR 中只有 Leader 分区, 这样就变成 acks 1 的情况了 Broker 端丢失
Broker 接收到数据后会将消息进行持久化到磁盘存储为了提高吞吐量和性能采用的是异步批量刷盘的策略也就是说按照一定的消息量和间隔时间进行刷盘。
首先会将数据存储到 PageCache 中至于什么时候将 Cache 中的数据刷盘是由操作系统根据自己的策略决定或者调用 fsync 命令进行强制刷盘。如果在同步到 Follower 分区前 Broker 宕机掉且选举了一个新的 Leader 分区那么落后的消息数据就会丢失。
既然 Broker 端消息存储是通过异步批量刷盘的那么就有可能会丢数据。由于 Kafka 中并没有提供同步刷盘的方式所以单个 Broker 还是很有可能丢失数据的。
kafka 通过多分区多副本机制已经可以最大限度的保证数据不丢失如果数据已经写入 PageCache 中但是还没来得及刷写到磁盘此时如果所在 Broker 突然宕机挂掉或者停电极端情况还是会造成数据丢失。
解决方案
Broker 端丢失消息是因为通过异步批量刷盘的策略先将数据存储到 PageCache再进行异步刷盘。
因此 Kafka 是通过多分区多副本的方式来最大限度的保证数据不丢失。可以通过以下参数配合来保证
unclean.leader.election.enable该参数表示有哪些 Follower 可以有资格被选举为 Leader , 如果一个 Follower 的数据落后 Leader 太多那么一旦它被选举为新的 Leader 数据就会丢失因此我们要将其设置为false防止此类情况发生。replication.factor该参数表示分区副本的个数。建议设置 replication.factor 3, 这样如果 Leader 副本挂掉Follower 副本会被选举为新的 Leader 副本继续提供服务。min.insync.replicas该参数表示消息至少要被写入成功到 ISR 多少个副本才算”已提交”建议设置min.insync.replicas 1, 这样才可以提升消息持久性保证数据不丢失。
另外还需要确保一下 replication.factor min.insync.replicas如果相等只要有一个副本挂掉整个分区就无法正常工作了因此推荐设置成 replication.factor min.insync.replicas 1, 最大限度保证系统可用性。 Consumer 端丢失
消息消费流程主要分为两个阶段
从 Broker 上拉取数据处理消息并提交 Offset 记录
Consumer 拉取后消息后需要提交 Offset 那么这里就可能会丢数据的。丢失原因如下
可能使用的自动提交 Offset 方式拉取消息后先提交 Offset后处理消息如果此时处理消息的时候异常宕机由于 Offset 已经提交了, 待 Consumer 重启后会从之前已提交的 Offset 下一个位置重新开始消费 之前未处理完成的消息不会被再次处理对于该 Consumer 来说消息就丢失了。拉取消息后先处理消息在进行提交 Offset 如果此时在提交之前发生异常宕机由于没有提交成功 Offset 待下次 Consumer 重启后还会从上次的 Offset 重新拉取消息不会出现消息丢失的情况 但是会出现重复消费的情况这里只能业务自己保证幂等性。
解决方案
Consumer 端丢失消息是因为在拉取完消息后提交 Offset 造成的因此为了不丢数据正确的做法是拉取数据、业务逻辑处理、提交消费 Offset 位移信息。
同时还需要设置参数 enable.auto.commit false采用手动提交位移的方式。另外对于消费消息重复的情况业务自己保证幂等性, 保证只成功消费一次即可。