Redis Cluster 宕机引发的事故(上)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 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个槽。可以查看 Github https://github.com/antirez/redis/issues/2576作者对此进行了解释。

 


四、分析

首先是查看程序启动异常信息,下图1为程序异常信息。



微信图片_20220121191358.jpg


图1异常很明显抛出的是连接异常


查看了Jedis的源码后发现初始化Redis Cluster的槽信息时,调用initializeSlotsCache()方法时出现异常。图2 为此方法的具体实现,分析代码发现此代码的目的应该是需要cache Redis Cluster槽信息,由于代码中有break,所以是只需要连接Redis获取一次信息即可。细一看此代码应该是有Bug,Try 的范围没有覆盖到Jedis连接的操作,如果Jedis连接失败直接抛出连接失败异常,此循环会直接退出,与代码实际预期不符合。


微信图片_20220121191412.jpg


图2


由此引发另一个思考,是不是我关闭的节点正好为循环的第一个节点导致此问题。尝试关闭另外一台从节点后程序正常启动。那么Jedis加载的节点顺序是什么,似乎Jedis对节点顺序进行了排序操作。在查看源码后发现Jedis重写了Redis节点配置类的hashCode方法。



微信图片_20220121191426.jpg

图3

image.png


输出结果:

[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这台节点,程序就会出现启动失败问题。



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8月前
|
NoSQL 算法 安全
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
323 0
|
8月前
|
存储 NoSQL 关系型数据库
Redis 日志篇:无畏宕机快速恢复的杀手锏
Redis 日志篇:无畏宕机快速恢复的杀手锏
153 0
|
7月前
|
存储 运维 NoSQL
Redis Cluster集群模式部署
Redis Cluster集群模式部署
135 4
|
8月前
|
存储 监控 负载均衡
redis 集群 (主从复制 哨兵模式 cluster)
redis 集群 (主从复制 哨兵模式 cluster)
|
5月前
|
存储 NoSQL 算法
深入理解Redis分片Cluster原理
本文深入探讨了Redis Cluster的分片原理,作为Redis官方提供的高可用性和高性能解决方案,Redis Cluster通过数据分片和横向扩展能力,有效降低单个主节点的压力。
深入理解Redis分片Cluster原理
|
5月前
|
缓存 NoSQL 网络协议
【Azure Redis 缓存】Azure Redis Cluster 在增加分片数时失败分析
【Azure Redis 缓存】Azure Redis Cluster 在增加分片数时失败分析
|
5月前
|
缓存 NoSQL Redis
【Azure Redis 缓存】Windows版创建 Redis Cluster 实验 (精简版)
【Azure Redis 缓存】Windows版创建 Redis Cluster 实验 (精简版)
|
5月前
|
NoSQL Redis
Redis——单机迁移cluster集群如何快速迁移
Redis——单机迁移cluster集群如何快速迁移
165 0
|
8月前
|
存储 负载均衡 监控
redis 集群模式(redis cluster)介绍
redis 集群模式(redis cluster)介绍
|
8月前
|
NoSQL 算法 关系型数据库
Redis宕机了,如何恢复数据
Redis持久化是为了防止服务宕机导致内存中数据丢失。主要有两种策略:RDB(快照)和AOF(仅追加文件)。RDB在指定时间间隔生成数据集快照,保存到磁盘,通过fork子进程实现,避免阻塞主线程,但可能丢失部分数据。AOF记录每次写操作,实时写回磁盘,提供秒级数据丢失保障,可通过不同同步策略平衡性能和安全性。AOF文件可定期重写以优化空间效率。混合使用RDB和AOF能在数据安全性和恢复速度上找到平衡。
125 1