Redis集群Lettuce主從切換問(wèn)題解決方案
一、問(wèn)題描述
Redis Cluster集群,當(dāng)master宕機(jī),主從切換,客戶端報(bào)錯(cuò) timed out
二、原因
SpringBoot2.X版本開始Redis默認(rèn)的連接池都是采用的Lettuce。當(dāng)節(jié)點(diǎn)發(fā)生改變后,Letture默認(rèn)是不會(huì)刷新節(jié)點(diǎn)拓?fù)涞摹?/p>
三、解決方案
3.1 方案一:把lettuce換成jedis
只需要在pom.xml里調(diào)整一下依賴的引用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
<!-- 不用lettuce ,用jedis -->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0-m4</version>
</dependency>3.2 方案二:刷新節(jié)點(diǎn)拓?fù)湟晥D
Redis節(jié)點(diǎn)異常,服務(wù)端的Redis集群拓?fù)浔凰⑿铝耍琂ava程序沒(méi)有獲取到新的拓?fù)洹?/p>
Lettuce官方文檔中關(guān)于Redis Cluster的相關(guān)說(shuō)明:Lettuce處理Moved和Ask永久重定向,由于命令重定向,你必須刷新節(jié)點(diǎn)拓?fù)湟晥D。而自適應(yīng)拓?fù)渌⑿拢ˋdaptive updates)與定時(shí)拓?fù)渌⑿拢≒eriodic updates)是默認(rèn)關(guān)閉的,可以通過(guò)如下代碼打開。
https://github.com/lettuce-io/lettuce-core/wiki/Redis-Cluster#user-content-refreshing-the-cluster-topology-view

修改代碼如下
package com.montnets.common.redis;
import io.lettuce.core.ClientOptions;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Component
public class RedisPoolConfig {
@Autowired
private RedisProperties redisProperties;
public GenericObjectPoolConfig<?> genericObjectPoolConfig(RedisProperties.Pool properties) {
GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(properties.getMaxActive());
config.setMaxIdle(properties.getMaxIdle());
config.setMinIdle(properties.getMinIdle());
if (properties.getTimeBetweenEvictionRuns() != null) {
config.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRuns().toMillis());
}
if (properties.getMaxWait() != null) {
config.setMaxWaitMillis(properties.getMaxWait().toMillis());
}
return config;
}
@Bean(destroyMethod = "destroy")
public LettuceConnectionFactory lettuceConnectionFactory() {
//開啟 自適應(yīng)集群拓?fù)渌⑿潞椭芷谕負(fù)渌⑿?
ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
// 開啟全部自適應(yīng)刷新
.enableAllAdaptiveRefreshTriggers() // 開啟自適應(yīng)刷新,自適應(yīng)刷新不開啟,Redis集群變更時(shí)將會(huì)導(dǎo)致連接異常
// 自適應(yīng)刷新超時(shí)時(shí)間(默認(rèn)30秒)
.adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30)) //默認(rèn)關(guān)閉開啟后時(shí)間為30秒
// 開周期刷新
.enablePeriodicRefresh(Duration.ofSeconds(20)) // 默認(rèn)關(guān)閉開啟后時(shí)間為60秒 ClusterTopologyRefreshOptions.DEFAULT_REFRESH_PERIOD 60 .enablePeriodicRefresh(Duration.ofSeconds(2)) = .enablePeriodicRefresh().refreshPeriod(Duration.ofSeconds(2))
.build();
// https://github.com/lettuce-io/lettuce-core/wiki/Client-Options
ClientOptions clientOptions = ClusterClientOptions.builder()
.topologyRefreshOptions(clusterTopologyRefreshOptions)
.build();
LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
.poolConfig(genericObjectPoolConfig(redisProperties.getJedis().getPool()))
//.readFrom(ReadFrom.MASTER_PREFERRED)
.clientOptions(clientOptions)
.commandTimeout(redisProperties.getTimeout()) //默認(rèn)RedisURI.DEFAULT_TIMEOUT 60
.build();
List<String> clusterNodes = redisProperties.getCluster().getNodes();
Set<RedisNode> nodes = new HashSet<RedisNode>();
clusterNodes.forEach(address -> nodes.add(new RedisNode(address.split(":")[0].trim(), Integer.valueOf(address.split(":")[1]))));
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
clusterConfiguration.setClusterNodes(nodes);
clusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
clusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(clusterConfiguration, clientConfig);
// lettuceConnectionFactory.setShareNativeConnection(false); //是否允許多個(gè)線程操作共用同一個(gè)緩存連接,默認(rèn)true,false時(shí)每個(gè)操作都將開辟新的連接
// lettuceConnectionFactory.resetConnection(); // 重置底層共享連接, 在接下來(lái)的訪問(wèn)時(shí)初始化
return lettuceConnectionFactory;
}
}以上就是Redis集群Lettuce主從切換問(wèn)題解決方案的詳細(xì)內(nèi)容,更多關(guān)于Redis集群Lettuce主從切換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù)的教程
RediSearch提供了一種簡(jiǎn)單快速的方法對(duì) hash 或者 json 類型數(shù)據(jù)的任何字段建立二級(jí)索引,然后就可以對(duì)被索引的 hash 或者 json 類型數(shù)據(jù)字段進(jìn)行搜索和聚合操作,這篇文章主要介紹了Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù),需要的朋友可以參考下2023-12-12
基于Redis 實(shí)現(xiàn)網(wǎng)站PV/UV數(shù)據(jù)統(tǒng)計(jì)
PV和UV是兩個(gè)重要的指標(biāo),本文主要介紹了基于Redis 實(shí)現(xiàn)網(wǎng)站PV/UV數(shù)據(jù)統(tǒng)計(jì),具有一定的參考價(jià)值,感興趣的可以了解一下2025-04-04
Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄的示例代碼
本文主要介紹了基于Redis如何實(shí)現(xiàn)短信驗(yàn)證碼登錄功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
如何自定義redis工具jar包供其他SpringBoot項(xiàng)目直接使用
這篇文章主要介紹了如何自定義redis工具jar包供其他SpringBoot項(xiàng)目直接使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Redis中一些最常見(jiàn)的面試問(wèn)題總結(jié)
Redis在互聯(lián)網(wǎng)技術(shù)存儲(chǔ)方面使用如此廣泛,幾乎所有的后端技術(shù)面試官都要在Redis的使用和原理方面對(duì)小伙伴們進(jìn)行各種刁難。下面這篇文章主要給大家總結(jié)介紹了關(guān)于Redis中一些最常見(jiàn)的面試問(wèn)題,需要的朋友可以參考下2018-09-09
CentOS系統(tǒng)安裝Redis及Redis的PHP擴(kuò)展詳解
這篇文章主要介紹了CentOS系統(tǒng)下安裝Redis數(shù)據(jù)的教程,以及詳解了Redis數(shù)據(jù)庫(kù)的PHP擴(kuò)展,文中介紹的很詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-12-12

