【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

Redis Cluster 宕机引发的事故

  • 2020-06-12
  • 本文字数:2160 字

    阅读完需:约 7 分钟

Redis Cluster 宕机引发的事故

导读:

Redis 官方号称支持并发 11 万读操作,并发 8 万写操作。由于优异的性能和方便的操作,相信很多人都在项目中都使用了 Redis,为了不让应用过分的依赖 Redis 服务,Redis 的作用只作为提升应用并发和降低应用响应时间存在,即使 Redis 出现异常,应用程序也不应该出现提供服务失败问题,对此拍拍信最近安排了一次全环境的 Redis Cluster 宕机演练。

本文作者系拍拍信架构负责人朱荣松和拍拍信架构开发工程师许彬,授权“技术锁话”进行发布。

一、演练过程

Redis 集群环境:


  1. 测试环境:

  2. Redis Cluster 配置 :Redis 3 主 3 从 一共 6 个节点。

  3. 预发环境:

  4. 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 个槽。可以查看 Github https://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)错误率
程序运行中关主(关任一主)10000010000030841000.031
关主(关任一主)10000010000014821020.015
关主(关任一主)100000100000305397.60.031
关从(关任一从)1000001000000109.20
关从(关任一从)100000100000090.10
关从(关任一从)100000100000088.90
主从一起关(关任一对)10000010000032613210.10.326
主从一起关(关任一对)10000010000029148169.80.291
主从一起关(关任一对)10000010000032410173.70.324
所有主全关100000100000100000353.41
所有从全关100000100000087.70
只留一台主100000100000100000357.11


表 1


从测试结果看,集群 Master 的选举过程是由 Master 参与选举的。


  1. 如果半数以上 Master 处于关闭状态那么整个集群处于不可用状态。

  2. 关闭任意一对主从节点会导致部分(大约为整个集群的 1/3)失败。

  3. 关闭任意一主,会导致部分写操作失败,是由于从节点不能执行写操作,在 Slave 升级为 Master 期间会有少量的失败。

  4. 关闭从节点对于整个集群没有影响。


2020-06-12 17:521061

评论

发布
暂无评论
发现更多内容

教你用Python 编写 Hadoop MapReduce 程序

华为云开发者联盟

Python hadoop 数据仓库 Hadoop Streaming Hadoop MapReduce

Cube 技术解读 | 支付宝新一代动态化技术架构与选型综述

蚂蚁集团移动开发平台 mPaaS

支付宝 mPaaS native 客户端 cube

【通知】2021年“绿城杯”网络安全大赛开始报名啦!

郑州埃文科技

架构实战营第一期 -- 模块八作业

clay

架构实战营

区块链 ≠ 分布式存储

趣链科技

区块链 分布式 存储

Python对文件的操作

在即

9月日更

数据通信网络基础

Regan Yue

华为数据通信 9月日更 数据通信

Phaser类在性能测试中应用

FunTester

多线程 性能测试 测试框架 FunTester phaser

孕蕾、护花、促果:展锐深耕芯片“三步曲”

脑极体

Growing 账号认证实践

GrowingIO技术专栏

spring security CAS SSO ldap

30天读完300页,这份Alibaba面试通关手册,助我“闯进”字节跳动拿下offer

Java spring 编程 架构

得偿所愿!字节4面斩下2-2Offer,入职就是30K16薪,相信你们也可以!

Java 程序员 字节跳动 面试 计算机

AUTOSAR基础篇之DTC

SOA开发者

软件 汽车 OTA ADAS

得物技术沙龙iOS专场

得物技术

ios 分享 周报 技术分享 技术沙龙

极客时间企业版|数字化转型专题讲座天津站圆满结束

InfoQ 天津

CANN AICPU算子耗时分析及优化探索

华为云开发者联盟

tensorflow 测试 算子 CANN算子 算子耗时

LDAP是什么意思?有什么用?

行云管家

运维 服务器 AD域 目录

解析鸿蒙内核消息队列QueueMail接口的哼哈二将

华为云开发者联盟

鸿蒙 接口 队列 消息队列 QueueMail

【WIC•资讯】世界智能大会组委会秘书处祝贺 2021中国(天津)非公有制经济发展论坛圆满召开

InfoQ 天津

字节4轮面试,拿43k*15 Offer!全靠过硬实力+1290题面试神技手册

Java 架构 面试 后端 计算机

Pulsar 用户案例|消息队列上云挑战与方案:腾讯云的 Apache Pulsar 实践

Apache Pulsar

Apache Pulsar

聊聊汽车ECU中单片机开发

SOA开发者

车载控制单元

【等保三级】过等保三级需要哪些设备?大概多少钱?

行云管家

网络安全 信息安全 等保 堡垒机 等保三级

一文搞懂如何使用Node.js进行TCP网络通信

华为云开发者联盟

node.js TCP 网络 网络通信 TCP服务器

k8s 驱逐pod疑惑

Geek_f24c45

Kubernetes kubelet

滨海新区新的社会阶层人士开展“寻美.天津”主题活动

InfoQ 天津

产品资讯 | mPaaS 10.1.68 适配 iOS 15

蚂蚁集团移动开发平台 mPaaS

ios 移动开发 mPaaS

书单 | 读了这10本书,再也不怕黑客攻击了

博文视点Broadview

一周信创舆情观察(9.6~9.12)

统小信uos

C++20 Concepts 极简介绍

董一凡

c++

足以封神的SpringCloudAlibaba问世,看过的人都已经“登仙”了

Java 程序员 面试 springboot 计算机

Redis Cluster 宕机引发的事故_文化 & 方法_技术琐话_InfoQ精选文章