一、版本
springboot1.5.2
Redis4.0.10
二、集群状况
模式:Cluster 集群
密码:有
三、依赖包
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<!--redis依赖-->
<!--默认继承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>
<!--redis 客户端-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
spring-boot-starter-data-redis版本是1.5.2
spring-data-redis版本是1.8.1(由spring-boot-starter-data-redis引入)
jedis版本是2.9.0
四、配置
#redis cluster
spring.redis.cluster.nodes=10.10.2.89:6379,10.10.2.89:6380,10.10.2.90:6379,10.10.2.90:6380,10.10.2.91:6379,10.10.2.91:6380
spring.redis.cluster.password =testpwd
spring.redis.cluster.timeout=2000
spring.redis.cluster.max-redirects=8
五、定义JedisCluster
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import java.util.HashSet;
import java.util.Set;
@Configuration
public class JedisClusterConfig {
//redis集群节点列表
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
//redis集群连接超时时间
@Value("${spring.redis.cluster.timeout}")
private Long timeout;
//redis集群最大连接次数
@Value("${spring.redis.cluster.max-redirects}")
private int redirects;
//redis集群连接密码
@Value("${spring.redis.cluster.password}")
private String password;
@Bean
//重写JedisConnectionFactory方法,注入密码,否则会报认证错误(这个初始化,在getJedisCluster()之前,所以没有读到密码)
public JedisConnectionFactory connectionFactory(){
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
connectionFactory.setPassword(password);
return connectionFactory;
}
@Bean
//定义JedisCluster对象
public JedisCluster getJedisCluster(){
String [] serverArray=clusterNodes.split(",");
Set<HostAndPort> nodes=new HashSet<>();
for (String ipPort:serverArray){
String [] ipPortPair=ipPort.split(":");
nodes.add(new HostAndPort(ipPortPair[0].trim(),Integer.valueOf(ipPortPair[1].trim())));
}
JedisCluster jedisCluster = new JedisCluster(nodes,timeout.intValue(),timeout.intValue(),redirects,password,new GenericObjectPoolConfig());
return jedisCluster;
}
}
六、踩坑
如果不重写JedisConnectionFactory,启动会报错
@Bean
//重写JedisConnectionFactory方法,注入密码,否则会报认证错误(这个初始化,在getJedisCluster()之前,所以没有读到密码)
public JedisConnectionFactory connectionFactory(){
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
connectionFactory.setPassword(password);
return connectionFactory;
}
错误
Caused by: redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.
at redis.clients.jedis.Protocol.processError(Protocol.java:127)
at redis.clients.jedis.Protocol.process(Protocol.java:161)
at redis.clients.jedis.Protocol.read(Protocol.java:215)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:285)
at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:291)
at redis.clients.jedis.Jedis.clusterSlots(Jedis.java:3376)
at redis.clients.jedis.JedisClusterInfoCache.discoverClusterNodesAndSlots(JedisClusterInfoCache.java:54)
at redis.clients.jedis.JedisClusterConnectionHandler.initializeSlotsCache(JedisClusterConnectionHandler.java:39)
at redis.clients.jedis.JedisClusterConnectionHandler.<init>(JedisClusterConnectionHandler.java:17)
at redis.clients.jedis.JedisSlotBasedConnectionHandler.<init>(JedisSlotBasedConnectionHandler.java:20)
at redis.clients.jedis.JedisSlotBasedConnectionHandler.<init>(JedisSlotBasedConnectionHandler.java:15)
at redis.clients.jedis.BinaryJedisCluster.<init>(BinaryJedisCluster.java:41)
at redis.clients.jedis.JedisCluster.<init>(JedisCluster.java:83)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createCluster(JedisConnectionFactory.java:306)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createCluster(JedisConnectionFactory.java:280)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.afterPropertiesSet(JedisConnectionFactory.java:241)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
定位
在默认初始化JedisConnectionFactory的时候,密码没有传入,那就重写,手动传入。
七、redis工具类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;
@Service
public class RedisUtil {
@Autowired
private JedisCluster cluster;
/**
* 对key存储的值做incr计数器
* @param key
* @param step
* @return
*/
public Long increment(final String key, final Long step) {
Long value = cluster.incrBy(key,step);
return value;
}
}
使用的时候,在业务类中
@Autowired private RedisUtil redisUtil;
注入使用