首先pom.xml文件,添加以下包:
org.springframework.data
spring-data-redis
1.8.4.RELEASE
在RedisClustersConfiguration.java配置中添加以下代码:
@Configuration
@PropertySource(value = "classpath:config.properties")
public class RedisClustersConfiguration {
@Value("${redis.pool.maxTotal}")
private int maxTotal;//最大连接数
@Value("${redis.pool.maxIdle}")
private int maxIdle;//最大空闲时间
@Value("${redis.pool.numTestsPerEvictionRun}")
private int numTestsPerEvictionRun;//每次最大连接数
@Value("${redis.pool.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;//释放扫描的扫描间隔
@Value("${redis.pool.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;//连接的最小空闲时间
@Value("${redis.pool.softMinEvictableIdleTimeMillis}")
private int softMinEvictableIdleTimeMillis;//连接控歘按时间多久后释放,当空闲时间>该值且空闲连接>最大空闲连接数时直接释放
@Value("${redis.pool.maxWaitMillis}")
private int maxWaitMillis;//获得链接时的最大等待毫秒数,小于0:阻塞不确定时间,默认-1
@Value("${redis.pool.testOnBorrow}")
private boolean testOnBorrow;//在获得链接的时候检查有效性,默认false
@Value("${redis.pool.testWhileIdle}")
private boolean testWhileIdle;//在空闲时检查有效性,默认false
@Value("${redis.pool.blockWhenExhausted}")
private boolean blockWhenExhausted;//false报异常,true阻塞超时 默认:true
@Value("${redis.cluster.connectionTimeout}")
private int connectionTimeout;
@Value("${redis.cluster.soTimeout}")
private int soTimeout;
@Value("${redis.cluster.maxRedirects}")
private int maxRedirects;
@Value("${redis.cluster.nodes}")
private String redisNodes;
@Value("${redis.cluster.password}")
private String password;
/**
*
* @return
*/
@Bean(name = "poolConfig")
@Profile({ "prod", "dev", "test" })
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig bean = new JedisPoolConfig();
bean.setMaxTotal(maxTotal);
bean.setMaxIdle(maxIdle);
bean.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
bean.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
bean.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
bean.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
bean.setMaxWaitMillis(maxWaitMillis);
bean.setTestOnBorrow(testOnBorrow);
bean.setTestWhileIdle(testWhileIdle);
bean.setBlockWhenExhausted(blockWhenExhausted);
return bean;
}
private Set getRedisNodes() {
Set jedisClusterNodes = new HashSet();
//解析集群配置
String[] clusterNodes = redisNodes.split(";");
for (String clusterNode : clusterNodes) {
String[] node = clusterNode.split(":");
String host = node[0];
int port = Integer.parseInt(node[1]);
jedisClusterNodes.add(new RedisNode(host, port));
}
return jedisClusterNodes;
}
/**
*
* @return
*/
@Bean(name = "clusterConfig")
@Profile({ "prod", "dev", "test" })
public RedisClusterConfiguration redisClusterConfiguration() {
RedisClusterConfiguration bean = new RedisClusterConfiguration();
bean.setMaxRedirects(maxRedirects);
bean.setClusterNodes(getRedisNodes());
return bean;
}
/**
*
* @param clusterConfig
* @param poolConfig
* @return
*/
@Bean(name = "jedisConnectionFactory")
public JedisConnectionFactory jedisConnectionFactory(RedisClusterConfiguration clusterConfig,
JedisPoolConfig poolConfig) {
JedisConnectionFactory bean = new JedisConnectionFactory(clusterConfig, poolConfig);
bean.setPassword(password);
return bean;
}
/**
*
* @return
*/
@Bean(name = "stringRedisSerializer")
public StringRedisSerializer stringRedisSerializer() {
return new StringRedisSerializer();
}
/**
*
* @param jedisConnectionFactory
* @param stringRedisSerializer
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean(name = "redisTemplateTransactional")
public RedisTemplate redisTemplateTransactional(JedisConnectionFactory jedisConnectionFactory,
StringRedisSerializer stringRedisSerializer) {
RedisTemplate bean = new RedisTemplate();
bean.setConnectionFactory(jedisConnectionFactory);
bean.setDefaultSerializer(stringRedisSerializer);
bean.setEnableTransactionSupport(true);
return bean;
}
/**
*
* @param jedisConnectionFactory
* @param stringRedisSerializer
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean(name = "redisTemplate")
public RedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory,
StringRedisSerializer stringRedisSerializer) {
RedisTemplate bean = new RedisTemplate();
bean.setConnectionFactory(jedisConnectionFactory);
bean.setDefaultSerializer(stringRedisSerializer);
bean.setEnableTransactionSupport(false);
return bean;
}
}
config.properties配置文件参考如下:
redis.pool.maxTotal=30
redis.pool.maxIdle=10
redis.pool.numTestsPerEvictionRun=1024
redis.pool.timeBetweenEvictionRunsMillis=30000
redis.pool.minEvictableIdleTimeMillis=1800000
redis.pool.softMinEvictableIdleTimeMillis=10000
redis.pool.maxWaitMillis=1500
redis.pool.testOnBorrow=true
redis.pool.testWhileIdle=true
redis.pool.blockWhenExhausted=false
redis.cluster.connectionTimeout=60000
redis.cluster.soTimeout=300000
redis.cluster.maxRedirects=8
redis.cluster.nodes=172.23.25.142:6379;172.23.25.142:6380;172.23.25.142:6381;172.23.25.142:6382;172.23.25.143:6379;172.23.25.143:6380;172.23.25.143:6381;172.23.25.143:6382;172.23.25.144:6379;172.23.25.144:6380;172.23.25.144:6381;172.23.25.144:6382
redis.cluster.password=
Service代码实现如下:
@Service
public class RedisTemplateServiceImpl implements RedisTemplateService{
/*
* redis集群使用事务时,会报MUTLI is currently not supported in cluster mode.
* Redis cluster对多key操作有限,要求命令中所有的key都属于一个slot,才可以被执行。
* 客户端可以对multi-key命令进行拆分,再发给redis。 目前还未找到比较好的解决方法,
* 所以在出现该错误的地方都用了非事务的redisTemplate。由于multi等命令不支持集群,
* 所以弃用,使用redis的lua脚本来完成事务,脚本功能被设计成可以与集群功能保持兼容。
* 但是脚本无法保证操作多key的原子性。
*/
@Autowired
private RedisTemplate redisTemplateTransactional;
@Autowired
private RedisTemplate redisTemplate;
@Override
public boolean hexists(final String key) {
return redisTemplate.execute(new RedisCallback() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
return connection.exists(key.getBytes());
}
});
}
@Override
public void del(String key) {
redisTemplate.delete(key);
}
@Override
public Long hincrby(String key, String hashkey, long value) {
return redisTemplate.opsForHash().increment(key, hashkey, value);
}
@Override
public void hset(String key, String hashkey, Object value) {
redisTemplate.opsForHash().put(key, hashkey, value);
}
@Override
public void hmset(String key, Map extends Object, ? extends Object> map) {
redisTemplate.opsForHash().putAll(key, map);
}
@Override
public String hget(String key, String hashkey) {
return (String) redisTemplate.opsForHash().get(key, hashkey);
}
@Override
public Long lpush(String key, String value) {
return redisTemplate.opsForList().leftPush(key, value);
}
@Override
public String rpop(String key) {
return redisTemplate.opsForList().rightPop(key);
}
}