WEBKT

生产事故!Redis 集群数据迁移踩坑实录与避坑指南

5 0 0 0

生产事故!Redis 集群数据迁移踩坑实录与避坑指南

一、事故回顾:迁移一时爽,事后火葬场

二、问题分析:知其然,更要知其所以然

三、解决方案:亡羊补牢,为时未晚

四、总结:防患于未然,胜于亡羊补牢

生产事故!Redis 集群数据迁移踩坑实录与避坑指南

大家好,我是老王,一个常年混迹于各种线上事故的运维老兵。

今天跟大家聊聊 Redis 集群数据迁移这个老生常谈,但又事故频发的话题。别看网上教程一大堆,真到生产环境,各种幺蛾子能让你怀疑人生。最近我就又双叒叕踩坑了,这次还差点搞出个大新闻。所以,痛定思痛,我决定把这次血泪教训分享出来,希望能帮各位兄弟姐妹们避避坑。

一、事故回顾:迁移一时爽,事后火葬场

事情是这样的,公司业务发展需要,原有的 Redis 集群容量告急,需要扩容。为了保证服务不停机,我们决定采用在线迁移的方式。简单来说,就是搭建一个新的 Redis 集群,然后把老集群的数据逐步迁移过去。

方案看着没毛病,我们也做了充分的测试。然而,现实总是残酷的。迁移过程中,出现了以下几个问题:

  1. 迁移速度慢如蜗牛: 原本预计几小时完成的迁移,硬生生拖了一天多。监控显示,迁移速度极不稳定,时快时慢,高峰期甚至出现停滞。
  2. 部分 Key 迁移失败: 迁移完成后,发现新集群中部分 Key 丢失,导致业务报错。更诡异的是,这些丢失的 Key 并没有规律可循,完全随机。
  3. 客户端连接异常: 迁移期间,部分客户端出现连接超时、连接被拒绝等异常,影响了部分业务的正常运行。
  4. 主从切换导致数据丢失: 在迁移接近尾声时,为了加速迁移,我们手动触发了一次主从切换。结果,切换后新集群的数据反而比切换前少了,部分新写入的数据丢失。

这些问题,每一个都足以让运维人员焦头烂额。更何况,它们还集中爆发了。我们紧急回滚,熬了几个通宵排查问题,才最终把服务恢复正常。

二、问题分析:知其然,更要知其所以然

事后复盘,我们对这次事故进行了深入分析,找到了问题的根源:

  1. 迁移速度慢:

    • 网络带宽瓶颈: 我们低估了数据迁移对网络带宽的消耗。老集群和新集群之间的网络带宽被打满,导致迁移速度受限。这就像你用一根吸管去抽一大桶水,速度自然快不起来。
    • 集群配置不合理: 老集群和新集群的配置不一致,例如,cluster-node-timeout 参数设置过小,导致集群频繁进行故障检测和主从切换,影响了迁移速度。就好比,你开着一辆老爷车去跑高速,自然跑不快。
    • 迁移工具选择不当: 我们最初使用的迁移工具,对大 Key 的处理效率较低。遇到包含大量元素的 Hash、List、Set、ZSet 等类型的 Key 时,迁移速度明显下降。这就好比,你用一把小勺子去舀一大锅粥,效率自然不高。
    • **客户端阻塞:**部分客户端使用了阻塞式的读取操作(如BLPOP,BRPOP),在读取的key不存在或者迁移过程中时,会造成客户端阻塞。阻塞的客户端多了,会影响迁移速度。
  2. Key 迁移失败:

    • 迁移工具 Bug: 我们使用的迁移工具存在一个已知的 Bug,在特定条件下会导致部分 Key 迁移失败。这个 Bug 就像一个隐藏的地雷,平时没事,一踩就炸。
    • Key 过期时间设置不当: 部分 Key 设置了较短的过期时间,在迁移过程中过期了,导致迁移失败。这就好比,你搬家的时候,有些东西还没搬到新家就坏了,自然就丢了。
    • 网络抖动: 迁移过程中,网络出现短暂抖动,导致部分迁移命令失败,进而导致 Key 丢失。这就好比,你搬家的时候,路上颠簸了一下,有些东西掉了,你却没发现。
  3. 客户端连接异常:

    • 客户端配置不当: 客户端连接池配置过小,无法满足迁移期间的连接需求,导致部分连接请求被拒绝。这就好比,你家门口的停车位太少,客人来了没地方停车,只能走人。
    • 集群状态不稳定: 迁移过程中,集群状态频繁变化,导致客户端无法及时更新集群拓扑信息,连接到错误的节点,进而导致连接异常。这就好比,你搬家了,但没告诉朋友新地址,朋友自然找不到你。
    • 客户端没有正确处理MOVEDASK错误。
  4. 主从切换导致数据丢失:

    • 主从同步延迟: 迁移过程中,主从节点之间存在数据同步延迟。手动触发主从切换时,从节点尚未完全同步主节点的数据,导致切换后数据丢失。这就好比,你把钱从一个银行账户转到另一个银行账户,还没到账你就把原来的账户注销了,钱自然就没了。
    • AOF 持久化配置不当: 我们使用的 AOF 持久化策略是 appendfsync everysec,这意味着每秒最多可能丢失 1 秒的数据。在主从切换时,这 1 秒的数据可能尚未同步到从节点,导致切换后数据丢失。这就好比,你每隔一分钟备份一次文件,突然电脑坏了,你最多可能丢失一分钟内编辑的内容。

三、解决方案:亡羊补牢,为时未晚

针对以上问题,我们采取了以下措施:

  1. 优化网络环境:

    • 扩容网络带宽: 我们临时升级了老集群和新集群之间的网络带宽,保证迁移期间的网络畅通。这就像把吸管换成了水管,抽水的速度自然快多了。
    • 使用专线网络: 如果条件允许,可以使用专线网络进行数据迁移,避免公网网络的不稳定因素。这就像你搬家的时候,走高速公路,避免了拥堵和红绿灯。
  2. 调整集群配置:

    • 合理设置 cluster-node-timeout 参数: 我们根据实际情况,适当调大了 cluster-node-timeout 参数,避免集群频繁进行故障检测和主从切换。这就像给老爷车换了新轮胎,让它跑得更稳。
    • 保证新老集群配置一致: 确保新老集群的配置尽可能一致,避免因配置差异导致迁移问题。这就像你搬家的时候,新家和老家的布局尽量一样,这样你才不会感到陌生。
  3. 更换迁移工具:

    • 使用官方推荐的迁移工具: 我们放弃了之前使用的迁移工具,改用 Redis 官方推荐的 redis-trib.rb 或者 redis-cli--cluster 模式进行迁移。这就像你搬家的时候,找了一家靠谱的搬家公司,避免了各种麻烦。
    • 针对大 Key 进行优化: 对于大 Key,我们可以采用分批迁移的方式,避免一次性迁移大量数据导致阻塞。这就像你搬家的时候,把大件家具拆开来搬,避免了卡在门口。

    可以使用scan命令配合migrate命令进行迁移。或者使用redis-shake工具。

  4. 优化客户端配置:

    • 增大客户端连接池: 我们适当调大了客户端连接池的大小,保证迁移期间有足够的连接可用。这就像你家门口的停车位增加了,客人来了都有地方停车。
    • 使用连接池管理工具: 使用连接池管理工具,例如 Jedis、Lettuce 等,可以更好地管理客户端连接,避免连接泄漏等问题。这就像你找了一个停车场管理员,帮你管理停车位,避免了各种混乱。
    • 客户端需要正确处理MOVEDASK错误,进行重定向。
  5. 避免手动触发主从切换:

    • 等待数据同步完成: 在迁移过程中,尽量避免手动触发主从切换。如果必须进行主从切换,一定要确保主从节点之间的数据同步完成。这就像你转账的时候,一定要等钱到账了再注销原来的账户。
    • 使用更安全的持久化策略: 如果对数据安全性要求较高,可以使用 appendfsync always 持久化策略,或者使用 RDB 持久化。这就像你每编辑一个字就备份一次文件,这样即使电脑坏了,你也不会丢失任何数据。
  6. 监控和告警

    • 迁移过程中,需要对集群状态,迁移进度,客户端连接数,主从延迟等指标进行密切监控。出现异常时,及时告警。

四、总结:防患于未然,胜于亡羊补牢

Redis 集群数据迁移是一个复杂的过程,涉及到网络、集群配置、迁移工具、客户端配置等多个方面。稍有不慎,就可能导致数据丢失、服务中断等严重后果。

希望通过这次事故的分享,能够帮助大家更好地理解 Redis 集群数据迁移的潜在风险,并采取相应的预防措施。记住,防患于未然,胜于亡羊补牢。

最后,再给大家提几点建议:

  • 做好充分的测试: 在生产环境进行迁移之前,一定要在测试环境进行充分的测试,模拟各种可能出现的情况,确保迁移方案的可靠性。
  • 制定详细的迁移计划: 迁移计划要尽可能详细,包括迁移步骤、时间安排、人员分工、应急预案等。
  • 做好数据备份: 在迁移之前,一定要对老集群的数据进行完整备份,以防万一。
  • 保持沟通畅通: 迁移过程中,要保持与开发团队、业务团队的沟通畅通,及时同步迁移进度和可能出现的问题。

好了,今天的分享就到这里。希望大家都能平平安安,顺顺利利,远离线上事故!

如果你还有其他关于 Redis 集群数据迁移的问题,欢迎在评论区留言,我会尽力解答。

运维老王 Redis集群数据迁移

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/7971