记一次 Redis Cluster 宕机引发的事故
关注我们,获得更多资源
导读:
Redis官方号称支持并发11万读操作,并发8万写操作。由于优异的性能和方便的操作,相信很多人都在项目中都使用了Redis,为了不让应用过分的依赖 Redis服务,Redis的作用只作为提升应用并发和降低应用响应时间存在,即使Redis出现异常,应用程序也不应该出现提供服务失败问题,对此拍拍信最近安排了一次全环境的Redis Cluster 宕机演练。
许彬:拍拍信架构负责人。
朱荣松:拍拍信架构开发工程师。
一、演练过程
Redis 集群环境:
1. 测试环境:
Redis Cluster 配置 :Redis 3主 3从 一共6个节点。
2. 预发环境:
Redis Cluster 配置 :Redis 3主 3从 一共6个节点。
下面是我们操作的时间线:
第一天
程序运行中关闭任意一台从节点,测试一天均无异常。
第二天
程序运行中关闭任意一台从节点,程序未发现异常,测试一天未发现异常。
第三天
预发环境有应用发版,出现异常程序无法启动。
……
二、问题描述
首先说明几个前提:
1. 测试与预发环境目前关闭的都是任意一台Redis从节点。
2. 测试环境经过反复测试无问题才开始关闭预发环境节点。
3. 预发环境重启被关闭的Redis节点后异常消失。
4. 连接Redis客户端使用的是Java语言中使用范围较广的Jedis。
那么为什么测试环境在经过反复测试没有问题,到预发环境会出现问题?
三、原理
分析问题前先简单解释下Redis Cluster实现原理。简单来说Redis Cluster中内置了 16384 个哈希槽,当需要在 Redis Cluster中存取一个 key或者value时,Redis 客户端先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数( 算法为:crc16(key)mod 16384),这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,值得注意的是这个计算key是在哪个槽上的操作是Redis 客户端做的操作,Java中常用的客户端为Jedis 这个也是被Spring推荐的一种客户端。
注: 如果有人好奇为什么Redis Cluster为什么会使用16384也就是2^14个槽。可以查看 Githubhttps://github.com/antirez/redis/issues/2576作者对此进行了解释。
四、分析
首先是查看程序启动异常信息,下图1为程序异常信息。
图1异常很明显抛出的是连接异常
查看了Jedis的源码后发现初始化Redis Cluster的槽信息时,调用initializeSlotsCache()方法时出现异常。图2 为此方法的具体实现,分析代码发现此代码的目的应该是需要cache Redis Cluster槽信息,由于代码中有break,所以是只需要连接Redis获取一次信息即可。细一看此代码应该是有Bug,Try 的范围没有覆盖到Jedis连接的操作,如果Jedis连接失败直接抛出连接失败异常,此循环会直接退出,与代码实际预期不符合。
图2
由此引发另一个思考,是不是我关闭的节点正好为循环的第一个节点导致此问题。尝试关闭另外一台从节点后程序正常启动。那么Jedis加载的节点顺序是什么,似乎Jedis对节点顺序进行了排序操作。在查看源码后发现Jedis重写了Redis节点配置类的hashCode方法。
图3
图4
下面简单测试下如果配置为:jedis-01.test.com、jedis-02.test.com、jedis-03.test.com、jedis-04.test.com、jedis-05.test.com、jedis-05.test.com输出顺序是什么。
图5
输出结果:
[redis-06.test.com:6379,redis-04.test.com:6379, redis-01.test.com:6379, redis-03.test.com:6379, redis-02.test.com:6379,redis-05.test.com:6379]
也就是说如果关闭redis-06.test.com:6379这台节点,程序就会出现启动失败问题。
五、解决
问题定位后首先去Github上的查看相关问题是否有人遇到,在查询后发现此问题有人在去年11月提了PR解决了此问题,链接如下:
https://github.com/xetorthio/jedis/pull/1633
官方目前释放出了2.10.0-m1和3.0.0-m1中解决了此问题,但是由于不是Release版本使用还得注意。解决的办法为图6,和图2对比可以发现图6对Jedis的实例化也进行了try catch。
图6
六、思考
Redis Cluster由于使用去中心化思想 ,图7 显示了Redis Cluster集群的状态,所以Redis Cluster 中如果有部分节点异常就会导致整个集群异常。
图7
那么问题来了多少节点异常会导致程序读写操作出现异常,下面我们也做了个简单的测试用于统计程序运行中,关闭Redis节点后程序的出错情况,以下测试表1仅供参考。
场景 |
操作(多节点均同时操作) |
Redis写总量 |
Redis读总量 |
错误量 |
总耗时(s) |
错误率 |
程序运行中 |
关主(关任一主) |
100000 |
100000 |
3084 |
100 |
0.031 |
关主(关任一主) |
100000 |
100000 |
1482 |
102 |
0.015 |
|
关主(关任一主) |
100000 |
100000 |
3053 |
97.6 |
0.031 |
|
关从(关任一从) |
100000 |
100000 |
0 |
109.2 |
0 |
|
关从(关任一从) |
100000 |
100000 |
0 |
90.1 |
0 |
|
关从(关任一从) |
100000 |
100000 |
0 |
88.9 |
0 |
|
主从一起关(关任一对) |
100000 |
100000 |
32613 |
210.1 |
0.326 |
|
主从一起关(关任一对) |
100000 |
100000 |
29148 |
169.8 |
0.291 |
|
主从一起关(关任一对) |
100000 |
100000 |
32410 |
173.7 |
0.324 |
|
所有主全关 |
100000 |
100000 |
100000 |
353.4 |
1 |
|
所有从全关 |
100000 |
100000 |
0 |
87.7 |
0 |
|
只留一台主 |
100000 |
100000 |
100000 |
357.1 |
1 |
表1
从测试结果看,集群Master的选举过程是由Master参与选举的。
1. 如果半数以上 Master 处于关闭状态那么整个集群处于不可用状态。
2. 关闭任意一对主从节点会导致部分(大约为整个集群的1/3)失败。
3. 关闭任意一主,会导致部分写操作失败,是由于从节点不能执行写操作,在Slave升级为Master期间会有少量的失败。
4. 关闭从节点对于整个集群没有影响。
转载自:技术琐话。
资源下载
关注公众号:数据和云(OraNews)回复关键字获取
2018DTCC , 数据库大会PPT
2018DTC,2018 DTC 大会 PPT
DBALIFE ,“DBA 的一天”海报
DBA04 ,DBA 手记4 电子书
122ARCH ,Oracle 12.2体系结构图
2018OOW ,Oracle OpenWorld 资料
PRELECTION ,大讲堂讲师课程资料
近期文章
企业数据架构的云化智能重构和变革(含大会PPT)
Oracle研发总裁Thomas Kurian加盟Google Cloud
变与不变: Undo构造一致性读的例外情况
Oracle 18c新特性:动态 Container Map 增强 Application Container 灵活性
Oracle 18c新特性:Schema-Only 帐号提升应用管理安全性
Oracle 18c新特性:多租户舰队 CDB Fleet (含PPT)
为什么看了那么多灾难,还是过不好备份这一关?
记一次 Redis Cluster 宕机引发的事故相关推荐
- Redis Cluster 宕机引发的事故
导读: Redis官方号称支持并发11万读操作,并发8万写操作.由于优异的性能和方便的操作,相信很多人都在项目中都使用了Redis,为了不让应用过分的依赖 Redis服务,Redis的作用只作为提升应 ...
- mysql cluster 宕机_MySQL InnDB Cluster 排错--dba.rejoinInstance()失败
最近在使用MySQL InnoDB Cluster中,遇到了一个比较大的问题. 问题背景: 在运行一个cluster中,其物理架构如下: 为了体验如何从整个cluster宕机到恢复的过程,本人手动将5 ...
- Redis 主节点宕机原因及解决方法
Redis 是一个基于内存的高性能键值存储系统,常用于缓存.消息队列等场景.Redis 支持主从复制,在主从复制中,主节点负责写入数据,从节点则负责读取数据.但是,Redis 主节点有可能会出现宕机的 ...
- Redis 无畏宕机快速恢复的杀手锏
" 特立独行是对的,融入圈子也是对的,重点是要想清楚自己向往怎样的生活,为此愿意付出怎样的代价. " 我们通常将 Redis 作为缓存使用,提高读取响应性能,一旦 Redis 宕机 ...
- 字节一面:Redis主节点宕机,如何处理?
微信搜索 [微观技术],关注这个不喜欢内卷的程序员. 精彩文章汇总 GitHub https://github.com/aalansehaiyang/technology-talk ,Star 12K ...
- Redis 主库宕机如何快速恢复?面试必问!
目录 什么是哨兵 原理 环境 设置哨兵 从宕机及恢复 主宕机及恢复 配置多个哨兵 1.什么是哨兵 哨兵是对Redis的系统的运行情况的监控,它是一个独立进程. 功能有二个: 监控主数据库和从数据库是否 ...
- mysql cluster 宕机 恢复_mysql cluster 集群恢复不起来,还请大神赐教?报错-问答-阿里云开发者社区-阿里云...
mysql cluster 集群原本使用的几乎全是内存表,后来随着数据的增长,把大的内存表迁移到磁盘表了,之后集群出现6050错误,整个集群挂掉:之后重新启动集群一直启动不起来... ----以下是集 ...
- 如果redis哨兵宕机了怎么办_Redis 主从复制架构中出现宕机怎么办?以及哨兵功能...
如果主从复制架构中出现宕机的情况,需要分情况看: 1. 从Redis宕机 相对而言比较简单,Redis从库重新启动后会自动加入到主从架构中,自动完成同步数据: 存在的问题是,如果从库在断开期间,主库变 ...
- Mysql 宕机引发索引丢失很可怕,文件 IO 中如何保证掉电不丢失数据?
欢迎关注方志朋的博客,回复"666"获面试宝典 众所周知,存储设计离不开文件 IO,将数据存储到文件中进行持久化,是大多数消息队列.数据库系统的常规操作.为了更贴近实际的生产场景, ...
最新文章
- 查看CentOS的网络带宽出口
- 英语 语义分割_Padlex数据处理-语义分割-分段变换,PaddleX,segtransforms
- 《Linux下sed命令的使用》
- ITK:布雷森汉姆线BresenhamLine
- OpenCV创建小部件Creating Widgets
- 决策树—ID3(源码解析)
- 俄罗斯无人机公司Hoversrf紧随Volocopter步伐,酷炫“方程式”飞行汽车来袭
- 数字图像处理(一):灰度变换和直方图处理
- 活动 | 日立·INNOWAY “引领变革 启迪未来” 创意马拉松
- 移动端媒体尺寸_网络推广外包浅析提升移动端网站建设效率有哪些网络推广外包技巧...
- MySQL之环境变量配置
- Cross Compile libdnet and Python for Montavista/PowerPC
- 无法创建新的分区也找不到现有的分区
- 教程:简单十步,在 iTunes 申请 App Store 退款
- JS实现视频录制-以Cesium为例
- E聊SDK-简介(1): 介绍
- 个人笔记,深入理解 JVM,很全!
- 计算机病毒青少年网上公约,《全国青少年网络文明公约》学习心得
- vim 写文档 (自身功能tags, txt2tags生成网页pdf等)
- 放大电路的静态工作点
热门文章
- 2017年大白菜系统操作说_为什么操作系统在2017年更重要
- 开源身份证识别_新的开源:金钱,公司和身份
- 开源 非开源_开源突破“舒适区”
- Kali Linux之软件安装、卸载、更新和修改更新源
- 传感器绕着世界坐标系旋转产生的疑惑
- html 拖放实现拼图游戏,Canvas drag 实现拖拽拼图小游戏
- java链表集合_Java底层基于链表实现集合和映射--集合Set操作详解
- 手机屏幕坏了如何把手机里面的资料取出来_手机碎屏原来也有这么多讲究,早了解这几个方法就不会被坑了...
- java ssm 项目_ssm开源java博客项目,基于maven搭建
- django的form常用字段和参数