记一次线上kafka造成的事故

当MySQL数据被删除并同步至Kafka,导致大量历史消息积压。由于消费速度跟不上生产速度,服务功能受到影响。解决方案包括在数据删除完成后重置offset,但需关闭消费组以防止消费者继续消费旧数据。offset重置通常涉及杀死消费进程或切换消费组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记一次线上kafka造成的事故

背景

背景:所有的原始数据均存储在mysql,mysql会通过binlog将数据同步至kafka消息队列,但是有人将mysql中的数据进行删除(大概有2、3年的数据),被删除的数据也通过binlog被同步至消息队列里导致大量消息积压,且该消息队列只有3个分区,最多3个线程消费,消费方即使过滤也远远赶不上生产的数据,导致大量消息积压,导致消费该kafka的服务功能几乎不可用。

解决方案

方案1:删除的数据不向kafka中生产。
方案2:mysql的删除操作为持续操作一直在进行,被删除的数据一直在向kafka中生产,即使重置offset也无法解决问题。等数据删除完毕后再重置offset。

重置kafka的offset

但是重置offset需要先关闭消费组消费,最好kill 掉,或者重新换个消费组。这是为啥呢?
比如,当前生产者的offset为1000,消费者的offset为100,此时想要直接消费offset为1000的数据,然后修改消费者端的offset为1000,然后消费者提交了1000,但是消费者还在继续消费啊,下次消费完就又向生产者提交了自己的offset101了,于是就又消费了老的数据。所以解决方法可以直接kill掉这个进程,然后重新设置offset再提交就可以了。

### 解决 MySQL 和 Redis 数据一致性问题 #### 延迟双删策略概述 为了确保 MySQL 和 Redis 的数据一致性,在分布式环境中采用延迟双删策略是一种常见做法。该方法的核心是在更新数据库的同时也更新缓存,但在某些极端情况下可能会导致两者之间的短暂不一致[^1]。 #### 实现细节 - **初次删除操作**:当接收到对某个键值的更新请求时,先立即从 Redis 中移除对应的缓存条目。 ```python redis.delete(key) ``` - **执行数据库写入**:随后向 MySQL 发起实际的数据变更指令。 ```sql UPDATE table_name SET column=value WHERE condition; ``` - **二次确认机制**:设定一定时间间隔后的再次验证过程,即所谓的“延迟”。如果在这段时间内发生了异常情况(比如网络波动),则重新尝试清除残留于 Redis 内部可能存在的旧版本录。 这一阶段可以通过定时任务来完成,也可以借助消息队列等异步工具实现更灵活的任务调度。 #### 处理延迟双删的具体措施 针对可能出现的问题,可以采取如下几种优化手段: - 使用可靠的消息中间件如 Kafka 或 RabbitMQ 来传递事件通知给负责清理工作的消费者组件; - 对每次涉及敏感字段变动的操作设置较短的有效期 TTL (Time To Live),从而减少因未及时刷新而造成的误读风险; - 配合 Canal 等开源项目监听 Binlog 日志变化并自动触发相应的维护动作,无需改动现有应用程序逻辑结构即可达成目的[^4]。 #### 双写场景的最佳实践建议 对于需要频繁交互的应用层面上,则应遵循以下原则以提高整体系统的稳定性和可靠性: - 尽量缩小事务边界范围内的并发度差异,防止因为锁竞争等原因引发不必要的性能瓶颈; - 明确区分不同类型资源间的依赖关系链路,避免形成循环等待局面进而造成死锁现象的发生; - 定期审查线上环境配置参数合理性以及监控指标健康状况,提前预防潜在隐患爆发的可能性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值