redis故障后记

最近线上系统还是不太平静,周五redis宕机又来了,暴露了不少问题。

系统中的代码是模仿jedis的源码实现,用jedis再封装的一套哨兵+分片的实现。回去把哨兵的机制又仔细学习了一遍,通过分析代码实现机制,初步分析有可能是客户端在处理主从切换上有些问题。

客户端库相关的issue

  • https://github.com/redis/jedis/pull/1566 bug描述:主从切换时,如果客户端和redis断开,会接收不到主从切换消息,导致保留旧的redis主信息
  • https://github.com/redis/jedis/issues/1910https://github.com/redis/jedis/pull/1911 bug描述:initPool和哨兵监听线程并行执行时存在race condition,可能无法感知到internalPool已经变化,导致保留旧的redis主信息

我们平时搞了那么多质量活动,根因分析,版本回溯,什么规范,流程, Checklist等,一个比一个厉害。结果还是该来,终究还是会来,陷入一个无限循环的怪圈中。

不过我们还是要吸取一下教训,看看后面有什么可以改进的, 简单写三点。

  • 核心中间件的掌控力。其实我们已经出现过多次的中间件相关的问题,通常我们都缺乏定位手段,甚至定位方向也比较抓瞎。主要表现在对工作机制原理理解不足,对中间件的配置选项不熟悉,对常见问题没有摸底预案,无法从报错现象,日志信息中快速定位问题。如果是开源中间件的话,其实资料案例还是比较多的。爹有娘有,不如自己有。这一块计划对目前使用的核心中间件进行梳理,按责任田的方式要求主动深入学习细节,总结分享。
  • 底层代码,公共代码要谨慎。上次有人调用redis的时候也出过问题。我们现在有些关键代码,底层代码都是由普通开发人员完成的,在可靠性,维护性,性能方面可能都存在隐患。最近的多个问题,也让我们感觉到,即使有经验,也要小心翼翼才可能写好。目前对这个方式主要还是committer要意识到风险,预防为主,让经验丰富的人去修改,找经验丰富的人来评审。
  • 可靠性测试要重视开展。这次的问题也暴露了我们怼非功能测试投入不足,对例如可靠性的场景测试的长期忽略。不过最近我们测试的同事也是意识到这一块的重要性的,例如尝试引入混沌工程的做法。特别是后续这种分布式,微服务构建的应用系统普遍存在,关系错综复杂,故障点可能出乎意料,上线有可能会出现各种奇怪的现象,甚至连锁反应,对系统的稳定性是极大的挑战。