Redis Cluster 在Spring中遇到的问题

news/2024/5/20 22:15:42

Redis集群配置可能会在运行时更改。可以添加新节点,可以更改特定插槽的主节点。还有可能因为master宕机或网络抖动等原因,引起了主从切换。

无法感知集群槽位变化

SpringBoot2.x 开始默认使用的 Redis 客户端由 Jedis 变成了 Lettuce,但是当 Redis 集群中节点槽位变化之后,Lettuce 将无法继续操作 Redis,原因在于此时 Lettuce 使用的仍然是有问题的连接信息。

实际上,Lettuce 支持 redis 集群拓扑动态刷新,但是默认并没有开启,SpringBoot 在集成 Lettuce 时默认也没有开启。并且在 SpringBoot2.3.0 之前,是没有配置项设置 Lettuce 自动刷新拓扑的。在这次提交中增加了这一配置。使用Jedis便没有这个问题。

官方的描述Lettuce需要刷新节点拓扑视图Lettuce Github Wiki

解决方案

方法一:使用Jedis连接

Spring Boot2.0以下默认使用Jedis,由于jedis通过自身异常反馈来识别重连、刷新服务端的集群信息机制,保证其自动故障恢复,所以Jedis client默认自动支持拓扑刷新,方法一便是使用更换为Jedis客户端。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>
</dependency>

方法二:配置LettuceConnectionFactory,设置拓扑刷新策略

文档参考集群特定选项

@Bean
public DefaultClientResources lettuceClientResources() {return DefaultClientResources.create();
}@Bean
public LettuceConnectionFactory lettuceConnectionFactory(RedisProperties redisProperties, ClientResources clientResources) {ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder().enablePeriodicRefresh(Duration.ofSeconds(30)) //按照周期刷新拓扑.enableAllAdaptiveRefreshTriggers() //根据事件刷新拓扑.build();ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()//redis命令超时时间,超时后才会使用新的拓扑信息重新建立连接.timeoutOptions(TimeoutOptions.enabled(Duration.ofSeconds(10))).topologyRefreshOptions(topologyRefreshOptions).build();LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder().clientResources(clientResources).clientOptions(clusterClientOptions).build();RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());clusterConfig.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());clusterConfig.setPassword(RedisPassword.of(redisProperties.getPassword()));LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(clusterConfig, clientConfiguration);return lettuceConnectionFactory;
}

方法三:开启自动拓扑刷新

Spring Boot2.3之后可以通过简单的配置变可以打开自动刷新拓扑的功能:

# 定时拓扑刷新(Periodic updates)
spring.redis.lettuce.cluster.refresh.period=60s
# 自适应拓扑刷新(Adaptive updates)
spring.redis.lettuce.cluster.refresh.adaptive=true

健康检查无法自动感知集群恢复

我们都知道Redis Cluster集群模式在主节点宕机后,会自动切换到可用的从节点,集群会再度恢复可用性。

但是如果在例如K8S、注册中心等管理服务中,存活探针用了actuator的health地址,那k8s容器里的服务也一样会down掉,也会导致服务不可用,即使服务层面已经刷新了redis集群的拓扑,服务/actuator/health健康情况依然会是down状态(原因是配置的redis集群nodes的每个node都会检查是否健康,不管这个node是主节点还是从节点),错误如下:

"redis": {"status": "DOWN","details": {"error": "org.springframework.data.redis.RedisConnectionFailureException: Redis connection failed; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 10.0.35.249:6380"}
},

redis cluster模式某节点宕机之后,Spring识别redis集群健康为down是个bug。是由于Spring Data Redis 2.2.8 提交所引起,具体可看这个解释。这个问题在spring boot2.4.x之后被修复。

解决方案

方法一:升级Spring版本到2.4.X

作者有在issue#21514下回应到,不会在2.3.X版本修复这个问题,而是在2.4.X中才会修改

方法二:重写健康检查代码

重写redis集群健康监控的Indicator,可以参考issue#21514下某网友的回答:

// 重新实现RedisReactiveHealthIndicatorprivate Health up(Health.Builder builder, Properties info, ReactiveRedisConnection connection) {if (connection instanceof ReactiveRedisClusterConnection) {List<Map<String, String>> details = getDetails(info);if (details.isEmpty()) {return builder.outOfService().build();} else {return builder.up().withDetail("nodes", details).build();}} else {return builder.up().withDetail("version", info.getProperty("redis_version")).build();}}private List<Map<String, String>> getDetails(Properties info) {return info.keySet().stream().map(String.class::cast).map(k -> k.substring(0, k.lastIndexOf("."))).distinct().sorted().map(node -> Map.of("node", node,"redis_version", info.getProperty(node + ".redis_version"),"role", info.getProperty(node + ".role"),"uptime_in_days", info.getProperty(node + ".uptime_in_days"))).collect(Collectors.toList());}

方法三:关闭Redis健康检查

management.health.redis.enabled=false

文档参考
RedisCluster集群模式下master宕机主从切换期间Lettuce连接Redis无法使用报错Redis command timed out的问题
redis集群拓扑结构自动更新:使用Lettuce连接Cluster集群实例时异常处理
刷新群集拓扑视图
Redis集群调整节点并手动切换主从引发的微服务报错问题
spring boot健康检查无法感知redis故障恢复的问题梳理
Redis集群模式下RedisReactiveHealthIndicator中断


http://www.mrgr.cn/p/12851177

相关文章

在Mac系统下搭建Selenium环境并驱动Chrome浏览器

本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器&#xff0c;虽然会有坑&#xff0c;但是我们可以凭借敏捷的身手躲过。下面就开始吧&#xff1a; 安装selenium 打开终端 ->pip安装&#xff08;安装命令&#xff1a;pip3 install selenium&#xff09; 安装浏览…

如何选择微信客户管理系统?

为何要给客户打上标签&#xff1f; 主要为企业搭建一个完善的客户体系&#xff0c;将客户资源整合&#xff0c;分层管理并进行针对性营销推广&#xff0c;以实现精准获客转化&#xff0c;简单来说就是更好的分类管理。 客户标签不应该只是作为的客户登记资料&#xff0c;后续每…

sublime配置less的一些坑(1)

仅在sublime的Install Package安装保存less报错 在sublime的Install Package安装less 打开sublime软件,按住CtrlShiftP组合键,弹出的界面中选择Install Package 选中后enter或者回车。等会弹出一个弹窗,大致意思是说你已经成功安装了package control。如果你在此之前已经安装了…

神经网络简单介绍

人工神经网络(artififial neural network) 简称神经网络&#xff0c;它是一种模仿生物神经网络结构和功能的非线性数学模型。 神经网络通过输入层接受原始特征信息&#xff0c;再通过隐藏层进行特征信息的加工和提取&#xff0c;最后通过输出层输出结果。 根据需要神经网络可以…

扫地机语音提示芯片,智能家居语音交互首选方案,WT588F02B-8S

智能家居已经成为现代家庭不可或缺的一部分&#xff0c;而语音交互技术正是智能家居的核心。在智能家居设备中&#xff0c;扫地机无疑是最受欢迎的产品之一。然而&#xff0c;要实现一个更智能的扫地机&#xff0c;需要一颗语音提示芯片&#xff0c;以提供高质量的语音交互体验…

使用 Docker 快速上手 Stability AI 的 SDXL 1.0 正式版

本篇文章&#xff0c;我们聊聊如何使用 Docker 来本地部署使用 Stability AI 刚刚推出的 SDXL 1.0&#xff0c;新一代的开源图片生成模型&#xff0c;以及在当前如何高效的使用显卡进行推理。 写在前面 好久没有写 Stable Diffusion 相关的内容了&#xff0c;趁着 SDXL 刚刚推…

Linux: 设置qmake的Qt版本

Qt开发&#xff0c;qmake会对应一个Qt版本&#xff0c;有时候需要切换这个版本&#xff0c;例如把qmake从Qt5.12切换到Qt5.9, 怎么操作呢&#xff1f; 案例如下&#xff1a; 银河麒麟V10系统&#xff0c;下载安装了Qt5.9.8&#xff0c;但是检查qmake发现它使用的是5.12.8&…

基于应用值迭代的马尔可夫决策过程(MDP)的策略的机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

labelme标签格式json转化成yolov8支持是数据集格式

我们用yolov8做实例分割时&#xff0c;需要制作标签&#xff0c;如果用labelme做&#xff0c;不能直接用模型训练&#xff0c;需要利用一个脚本文件进行转换。 import base64 import random import shutil from tqdm import tqdm import math import json import os import nu…

RocketMQ集群4.9.2升级4.9.6版本

本文主要记录生产环境短暂停机升级RocketMQ版本的过程 一、整体思路 1.将生产环境MQ4.9.2集群同步到测试环境&#xff0c;并启动&#xff0c;确保正常运行。 2.参照4.9.2配置4.9.6集群 3.停掉4.9.2集群&#xff0c;启动4.9.6集群&#xff0c;测试确保正常运行。 4.停掉4.9.6集…

计算机视觉实验:图像增强应用实践

本次实验主要从基于统计、函数映射的图像增强方法和基于滤波的图像增强方法两种方法中对一些图像增强的算法进行实现。主要的编程语言为python&#xff0c;调用了python自带的PIL图像库用于读取图像&#xff0c;利用numpy进行图像运算&#xff0c;最后使用opencv第三方库进行对…

2023-07-31力扣每日一题

链接&#xff1a; 143. 重排链表 题意&#xff1a; 将链表L0 → L1 → … → Ln - 1 → Ln变成L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 解&#xff1a; 线性表法还是好写的 这边搞一下翻转法&#xff0c;快慢指针求翻转点&#xff08;翻转后面一半然后双指针合并…

shell脚本:数据库的分库分表

#!/bin/bash ######################### #File name:db_fen.sh #Version:v1.0 #Email:admintest.com #Created time:2023-07-29 09:18:52 #Description: ########################## MySQL连接信息 db_user"root" db_password"RedHat123" db_cmd"-u${…

第五章 Opencv图像处理框架实战 5-3 图像阈值与平滑处理

图像阈值 ret, dst cv2.threshold(src, thresh, maxval, type) src&#xff1a; 输入图&#xff0c;只能输入单通道图像&#xff0c;通常来说为灰度图 dst&#xff1a; 输出图 thresh&#xff1a; 阈值 maxval&#xff1a; 当像素值超过了阈值&#xff08;或者小于阈值&am…

产品开发八大模块交流︱奇瑞新能源汽车产品开发院院长荣升格

奇瑞新能源汽车股份有限公司研发中心/产品开发院院长荣升格先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;产品开发八大模块交流。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; VUCA时代…

Linux之 环境变量

什么是环境变量 windows中也有个 Linux 环境变量 env linux和windows环境变量&#xff0c;功能类似的&#xff0c; windows系统的环境变量&#xff0c;在cmd中可以之间调用程序运行。这些程序的执行程序的路径&#xff0c;一般编辑在path变量中 环境变量都分全局的&#xff…

想做上位机,学C#还是QT?

学习C#还是Qt&#xff0c;取决于你的具体需求和偏好。 如果你计划开发跨平台的桌面应用程序&#xff0c;并且希望使用一种更轻量级、直观的界面框架&#xff0c;那么Qt可能是一个不错的选择。Qt是一个功能丰富且成熟的跨平台框架&#xff0c;支持多种开发语言&#xff08;包括…

[个人笔记] Windows配置NTP时间同步

Windows - 运维篇 第六章 Windows配置NTP时间同步 Windows - 运维篇系列文章回顾Windows配置NTP时间同步域控环境的NTP配置工作组环境的NTP配置Windows的CMD部分命令集 参考来源 系列文章回顾 第一章 迁移WinSrv系统到虚拟机 第二章 本地安全策略xcopy实现实时备份文件夹内容 …

[golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务

本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解 一.Captcha验证码功能引入 在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能 编辑 这个验证码功能…

SBFI AM(Na+Indicator),129423-53-6,可用来预测纯化线粒体Na+梯

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ SBFI AM(NaIndicator)钠离子荧光探针 PART1----​Product structure&#xff1a; PART2----​Product specifications&#xff1a; 1.CAS No&#xff1a;129423-53-6 2.Molecular formula&#xff1a;C56H58N2O23 3.Molec…