远程连接代码
使用jedis,将默认的lettuce客户端除外
pom.xml
<!--redis-->
<!--属性配置支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--默认继承lettuce,切换成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>
读取节点的代码:
/**
* redis 集群配置属性
*/
@Component
@Validated
@Data
@ConfigurationProperties(value = "spring.redis.cluster")
@PropertySource(value = "classpath:application.yml")
public class RedisClusterProperty {
/**
* 集群节点的主机名
* spring.redis.cluster.nodes[0] =
* spring.redis.cluster.nodes[1] =
* spring.redis.cluster.nodes[1] =
*/
private List<String> nodes;
}
将节点注入到连接工厂:
/**
*
* (1)将配置文件注入到RedisConnectionFactory
* (2)redis集群必须redis 3.0以上版本的支持
*/
@Configuration
@Component
public class JedisClusterConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(JedisClusterConfig.class);
@Autowired
private RedisClusterProperty redisClusterProperty;
/**
* Spring Data Redis 1.7 支持redis集群
* jedis集群配置
*
* @return
*/
@Bean
@Primary
public RedisConnectionFactory connectionFactory() {
RedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory(
new RedisClusterConfiguration(redisClusterProperty.getNodes()));
return redisConnectionFactory;
}
}
application.yml
##########################################################################
# redis
##########################################################################
spring:
redis:
cluster:
# 只需要添加三个master节点
nodes: 192.168.48.142:8000,192.168.48.142:8001,192.168.48.142:8002
# 节点之间最大转发次数
max-redirects: 2
工具类:redis无法序列化Object,可以用Jackson工具序列化即可。
/**
* redis对object对象的封装
*/
@Configuration
@EnableCaching
public class RedisObjectUtils extends CachingConfigurerSupport {
/**
* 选择redis作为默认缓存工具
* (2.x版本和1.5x版本传参数不一样,创建rediscach也不一样)
*
* @param redisConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return RedisCacheManager.create(redisConnectionFactory);
}
/**
* 设置序列化和反序列化对象
*
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
// key序列化
redisTemplate.setKeySerializer(stringSerializer);
// value序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Hash key序列化
redisTemplate.setHashKeySerializer(stringSerializer);
// Hash value序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 对hash类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
/**
* 对redis字符串类型数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
/**
* 对链表类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
/**
* 对无序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
/**
* 对有序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}
工具类:操作string
/**
* redis对string的操作的封装
*/
@Component
public class RedisStringUtils {
@Autowired
private RedisTemplate<String,String> redisTemplate;
/**
* 默认过期时长 1天,单位:秒
*/
public static final long DEFAULT_EXPIRE = 60 * 60 * 24;
/**
* 不设置过期时长
*/
public static final long NOT_EXPIRE = -1;
/**
* 判断key是否存在
*
* @param key
* @return
*/
public boolean existsKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 重名名key,如果newKey已经存在,则newKey的原值被覆盖
*
* @param oldKey
* @param newKey
*/
public void renameKey(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
/**
* newKey不存在时才重命名
*
* @param oldKey
* @param newKey
* @return 修改成功返回true
*/
public boolean renameKeyNotExist(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
/**
* 删除key
*
* @param key
*/
public void deleteKey(String key) {
redisTemplate.delete(key);
}
/**
* 删除多个key
*
* @param keys
*/
public void deleteKey(String... keys) {
Set<String> kSet = Stream.of(keys).collect(Collectors.toSet());
redisTemplate.delete(kSet);
}
/**
* 删除Key的集合
*
* @param keys
*/
public void deleteKey(Collection<String> keys) {
Set<String> kSet = keys.stream().collect(Collectors.toSet());
redisTemplate.delete(kSet);
}
/**
* 设置key的生命周期
*
* @param key
* @param time
* @param timeUnit
*/
public void expireKey(String key, long time, TimeUnit timeUnit) {
redisTemplate.expire(key, time, timeUnit);
}
/**
* 指定key在指定的日期过期
*
* @param key
* @param date
*/
public void expireKeyAt(String key, Date date) {
redisTemplate.expireAt(key, date);
}
/**
* 查询key的有效期
*
* @param key
* @param timeUnit
* @return
*/
public long getKeyExpire(String key, TimeUnit timeUnit) {
return redisTemplate.getExpire(key, timeUnit);
}
/**
* 将key设置为永久有效
*
* @param key
*/
public void persistKey(String key) {
redisTemplate.persist(key);
}
/**
* 设置值
* @param key
* @param value
*/
public void opsForValueSet(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 获取值
* @param key
*/
public String opsForValueGet(String key) {
return redisTemplate.opsForValue().get(key);
}
}
程序报错:
org.springframework.data.redis.TooManyClusterRedirectionsException: No more cluster attempts left.; nested exception is redis.clients.jedis.exceptions.JedisClusterMaxAttemptsException: No more cluster attempts left.
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:55)
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:42)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
百度出了以下解决方案:
1、redis.conf里面的”bind IP地址“是限制访问IP的,需要注释掉
2、使用ruby命令开启集群,要使用公网IP,如下:
#注意一定不要用127.0.0.1这种本地的局域ip,要用公网ip
ruby redis-trib.rb create --replicas 1 公网IP:7000 公网IP:7001 公网IP:7002 公网IP:7003 公网IP:7004 公网IP:7005
上面的:–replicas 1 公网IP:7000 公网IP:7001 … … 都要使用非本地的其他设备在局域网内能访问到的ip,不要使用127.0.0.1。(我的就是这里弄错了,调整这里之后解决了)
3、如果执行2步骤一直在“Waiting for the cluster to join…”,那肯定是你端口没有开启,不要质疑,这里的端口不是7000-7005,而是17000-17005,因为redis设置集群的端口号是”redis端口+10000“,这个非常重要。
开始尝试1------修改redis端口
因为配置文件原本就没有binding 127.0.0.1,排除这种可能。
异常如下:
org.springframework.data.redis.RedisConnectionFailureException: No reachable node in cluster; nested exception is redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException: No reachable node in cluster
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:65)
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:42)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
开始尝试2---- 重新搭建redis cluster
参考教程:
https://blog.csdn.net/u010649766/article/details/79629526
https://blog.51cto.com/13544424/2058280
中途因为原来的配置导致节点之间互相已经建立了联系,可以删除他们的rbd和config文件即可。
最终问题解决了。