首先pom.xml文件,添加以下包:
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-redis</artifactId>
- <version>1.8.4.RELEASE</version>
- </dependency>
在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<RedisNode> getRedisNodes() {
- Set<RedisNode> jedisClusterNodes = new HashSet<RedisNode>();
- //解析集群配置
- 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<String, String> redisTemplateTransactional;
- @Autowired
- private RedisTemplate<String, String> redisTemplate;
-
- @Override
- public boolean hexists(final String key) {
- return redisTemplate.execute(new RedisCallback<Boolean>() {
- @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);
- }
- }