【AKS+Redis】AKS中客户端(ioredis)遇见Azure Redis服务Failover后链接中断的可能性

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 在AKS中,NodeJS应用使用ioredis连接Redis时,在Redis升级或故障转移时可能出现长时间无法恢复连接的问题。这可能由于TCP重连机制,默认可能等待13分钟。为解决此问题,可以调整Linux的TCP设置(如`net.ipv4.tcp_retries2`设为5),并利用ioredis的`retryStrategy`选项自定义重连策略,减少延迟。参考[ioredis文档](https://github.com/redis/ioredis?tab=readme-ov-file#auto-reconnect)以优化重连行为。

问题描述

在AKS中连接Redis,当遇到Azure Redis 升级或者Failover时,NodeJS应用中使用ioredis sdk 在很长一段时间内无法恢复和 Azure Redis服务端的连接,对于这种想象的可能性推断。

 

问题解答

使用 Azure Cache for Redis 时,一个服务器是主节点,另一个服务器是副本。 主节点通常负责为来自客户端的写入和读取请求提供服务。 在执行写入操作时,它会向其内部内存提交一个新密钥和密钥更新,并立即回复客户端。 它以异步方式将操作转发给副本。

当发生升级或者是Failover时,Azure Redis服务会执行以下操作:

  1. 首先修补副本节点(Replica)。
  2. 修补的副本以协作方式将自身提升为主副本。 这种升级被视为计划性故障转移。
  3. 以前的主节点将重新启动以接受新的更改,并作为副本节点备份。
  4. 副本节点连接到主节点并同步数据。
  5. 数据同步完成后,将对剩余的节点重复修补过程。

 

在Redis的升级/故障转移(Failover)中,会出现之前的链接全部断开,然后重连的情况。所以非常考验Redis SDK的复原设计能力。

在公网上搜索,遇见有类似的问题: 一个关于 redis 长链接的问题 · Issue #1615

当 redis1 挂掉以后(比如直接电源关机),这个时候 node 客户端这边大约要等10 分钟左右才能成功连接成功 ....

 

Redis SDK中,Redis Client使用的TCP Connection依赖TCP的重连机制,如果遇到Redis的Failover,TCP连接将一直尝试重传,直到十几分钟后才会创建一个新的TCP连接, 这部分在Azure Redis的文档中(

Linux 托管客户端应用程序的 TCP 设置) 有非常详细的介绍:

某些 Linux 版本中的默认 TCP 设置可能会导致 Redis 服务器连接失败 13 分钟或更长时间。 默认设置可以防止客户端应用程序检测关闭的连接,并在连接未正常关闭的情况下防止自动还原这些关闭的连接。

如果网络连接中断或 Redis 服务器脱机进行计划外维护,重新建立连接可能会失败。

建议使用以下 TCP 设置:

设置
net.ipv4.tcp_retries2 5

有关此方案的详细信息,请参阅在 Linux 上运行时,长达 15 分钟无法重新建立连接。 虽然此讨论与 StackExchange.Redis 库有关,但 Linux 上运行的其他客户端库也会受到影响。 该说明仍然有用,可以通用化到其他库。

 

所以,继续查看 ioredis文档的重连配置,寻找可以避免出现长达十分钟以上无法连接Redis服务的问题:

Auto-reconnect 自动重新连接

默认情况下,当与 Redis 的连接丢失时,ioredis 会尝试重新连接,除非通过 redis.disconnect()redis.quit() 手动关闭连接。

使用 retryStrategy 选项可以非常灵活地控制断开连接后等待多长时间重新连接:


const redis =

new Redis({

 // This is the default value of `retryStrategy`

 retryStrategy(times) {

   const delay = Math.min(times * 50, 2000);

   return delay;

 },

});


retryStrategy 是一个在连接丢失时将被调用的函数。

参数 times 表示这是第 n 次重新连接,返回值表示等待重新连接的时间(以毫秒为单位)。

当返回值不是数字时,ioredis将停止尝试重新连接,如果用户不手动调用 redis.connect() ,连接将永远丢失。

 

 

参考资料

ioredis auto-reconnect: https://github.com/redis/ioredis?tab=readme-ov-file#auto-reconnect

Linux 托管客户端应用程序的 TCP 设置:https://docs.azure.cn/zh-cn/azure-cache-for-redis/cache-best-practices-connection#tcp-settings-for-linux-hosted-client-applications

一个关于 redis 长链接的问题https://github.com/redis/ioredis/issues/1615




当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

相关实践学习
基于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
相关文章
|
6天前
|
存储 NoSQL 关系型数据库
Redis系列学习文章分享---第一篇(Redis快速入门之初始Redis--NoSql+安装redis+客户端+常用命令)
Redis系列学习文章分享---第一篇(Redis快速入门之初始Redis--NoSql+安装redis+客户端+常用命令)
21 1
|
6天前
|
NoSQL Java Redis
通过Redis 实现分布式锁_利用Jedis 客户端
通过Redis 实现分布式锁_利用Jedis 客户端
|
6天前
|
缓存 NoSQL Java
Redis系列学习文章分享---第四篇(Redis快速入门之Java客户端--商户查询缓存+更新+双写一致+穿透+雪崩+击穿+工具封装)
Redis系列学习文章分享---第四篇(Redis快速入门之Java客户端--商户查询缓存+更新+双写一致+穿透+雪崩+击穿+工具封装)
12 0
|
6天前
|
存储 NoSQL Java
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
11 0
|
6天前
|
存储 NoSQL Java
Redis系列学习文章分享---第二篇(Redis快速入门之Java客户端--Jedis+连接池+SpringDataRedis+RedisTemplate+RedisSerializer+Hash)
Redis系列学习文章分享---第二篇(Redis快速入门之Java客户端--Jedis+连接池+SpringDataRedis+RedisTemplate+RedisSerializer+Hash)
12 0
|
1月前
|
NoSQL 大数据 Redis
分享5款.NET开源免费的Redis客户端组件库
分享5款.NET开源免费的Redis客户端组件库
|
18天前
|
存储 运维 NoSQL
Redis Cluster集群模式部署
Redis Cluster集群模式部署
46 4
|
20天前
|
监控 NoSQL 算法
手把手教你如何搭建redis集群(二)
手把手教你如何搭建redis集群(二)
37 1
|
20天前
|
存储 NoSQL 容灾
手把手教你如何搭建redis集群(一)
手把手教你如何搭建redis集群(一)
37 1