Redis集群宕掉一台master,恢复master后,spring服务报:CLUSTERDOWN The cluster is down

为了测试redis集群高可用,启动三主三从,kill掉一台master后,redis集群会slave自动切换到master,这都没有问题,但是客户端springboot服务报错,报错信息如下:

报错信息:

io.lettuce.core.RedisCommandExecutionException: CLUSTERDOWN The cluster is down] with root cause
io.lettuce.core.RedisCommandExecutionException: CLUSTERDOWN The cluster is down
at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:135)
at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:108)
at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120)
at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111)
at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:59)
at io.lettuce.core.cluster.ClusterCommand.complete(ClusterCommand.java:63)
at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:654)
at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:614)
at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:565)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline H e a d C o n t e x t . c h a n n e l R e a d ( D e f a u l t C h a n n e l P i p e l i n e . j a v a : 1410 ) a t i o . n e t t y . c h a n n e l . A b s t r a c t C h a n n e l H a n d l e r C o n t e x t . i n v o k e C h a n n e l R e a d ( A b s t r a c t C h a n n e l H a n d l e r C o n t e x t . j a v a : 379 ) a t i o . n e t t y . c h a n n e l . A b s t r a c t C h a n n e l H a n d l e r C o n t e x t . i n v o k e C h a n n e l R e a d ( A b s t r a c t C h a n n e l H a n d l e r C o n t e x t . j a v a : 365 ) a t i o . n e t t y . c h a n n e l . D e f a u l t C h a n n e l P i p e l i n e . f i r e C h a n n e l R e a d ( D e f a u l t C h a n n e l P i p e l i n e . j a v a : 919 ) a t i o . n e t t y . c h a n n e l . n i o . A b s t r a c t N i o B y t e C h a n n e l HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel HeadContext.channelRead(DefaultChannelPipeline.java:1410)atio.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)atio.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)atio.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)atio.netty.channel.nio.AbstractNioByteChannelNioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:745)`


解决方案:

spring:
  application:
    name: lizz-gateway
  #***********************redis***********************
  redis: #redis配置
    lettuce: #lettuce客户端配置
      pool: #连接池配置
        max-active: 50 # 连接池最大连接数(使用负值表示没有限制) 默认 8
        max-wait: 10 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
        max-idle: 20 # 连接池中的最大空闲连接 默认 8
        min-idle: 10 # 连接池中的最小空闲连接 默认 0
      cluster:
        refresh: #集群刷新
          adaptive: true #自动刷新集群 默认false关闭
#          period: 10M #定时刷新
    timeout: 1000 # 连接超时时间(毫秒)
    cluster: #集群配置
      nodes: #集群节点
        - 10.2.55.88:7001
        - 10.2.55.88:7002
        - 10.2.55.88:7003
        - 10.2.55.88:7004
        - 10.2.55.88:7005
        - 10.2.55.88:7006
      max-redirects: 3 #集群中重定向最大次数

配置cluster.refresh.adaptive等于true,自动刷新集群

如果上面方案不可用,则在pom.xml新增依赖

        <dependency>
		    <groupId>redis.clients</groupId>
		    <artifactId>jedis</artifactId>
		</dependency>
		<dependency>
		    <groupId>redis.clients</groupId>
	        <artifactId>jedis</artifactId>
	        <version>3.7.0</version>
        </dependency>
        <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>

重启服务即可,以后就不出出现了

### Redis Sentinel 配置从节点同步并连接主节点 #### 1. 主节点配置 在 Redis 的主节点上,需要确保其 `redis.conf` 文件已经正确配置。以下是关键参数: - **bind**: 绑定 IP 地址,默认绑定的是本地地址 (127.0.0.1),如果是分布式环境,建议修改为实际的服务器 IP 地址。 - **port**: 设置监听端口,默认是 6379。 - **requirepass**: 如果启用了密码验证,设置访问密码。 ```bash # redis.conf bind 192.168.32.131 port 6379 protected-mode no daemonize yes logfile "/var/log/redis_6379.log" dir /data appendonly yes ``` 完成以上配置后,启动 Redis 主节点服务[^4]。 --- #### 2. 从节点配置 从节点也需要有自己的 `redis.conf` 文件,并指定主节点的信息以便进行数据同步。以下是关键步骤: - 修改 `slaveof` 参数,指向主节点的 IP 和端口号。 - 启动从节点的服务。 ```bash # redis.conf slaveof 192.168.32.131 6379 masterauth your_password_if_set_in_master ``` 完成后,启动从节点服务: ```bash redis-server /path/to/redis.conf ``` 此时,从节点会自动尝试与主节点建立连接,并开始同步数据。 --- #### 3. Sentinel 节点配置 Sentinel 是用于监控 Redis 数据节点健康状态以及实现高可用性的组件。为了使 Sentinel 正确管理主从关系,需在其配置文件中定义以下内容: - 指定要监控的主节点名称及其初始信息。 - 设置 quorum 数量(即多少个 Sentinel 认为主节点不可用时才触发故障转移)。 - 下线时间阈值 (`down-after-milliseconds`)。 示例配置如下: ```ini # sentinel.conf sentinel monitor mymaster 192.168.32.131 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1 ``` 启动 Sentinel 实例: ```bash redis-sentinel /path/to/sentinel.conf ``` 重复此过程,在其他机器上也部署多个 Sentinel 节点以增强可靠性[^2]。 --- #### 4. 故障切换机制概述 当某个 Sentinel 发现主节点无法响应超过设定的时间(`down-after-milliseconds`),它会将其标记为“主观下线”。如果有足够的 Sentinel 达成一致意见,则进入“客观下线”阶段。随后,这些 Sentinels 将协商选出一个新的主节点,通常是当前性能最佳的一个从节点[^3]。 --- #### 5. 测试连通性和功能 可以通过执行以下命令测试主从复制和 Sentinel 功能是否正常工作: - 连接到任意一个 Redis 或 Sentinel 节点,运行 `INFO replication` 查看主从状态。 - 使用 `SENTINEL get-master-addr-by-name mymaster` 查询当前主节点的位置。 --- ### 示例代码:Spring Boot 配置 Redis Cluster 如果计划通过 Spring Boot 应用程序操作这个集群,可以参考以下配置方式: ```yaml spring: redis: host: 192.168.32.131 # 可替换为 Sentinel 提供的实际主节点地址 port: 6379 password: your_redis_password lettuce: cluster: refresh: adaptive: true period: PT5S ``` 或者直接利用 Jedis/Spring Data Redis API 编写逻辑处理动态获取 Master 地址的功能。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值