Redis集羣配置

1.Java類

package org.atm.dc.app.util;

import java.io.Closeable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.BinaryJedisCluster;
import redis.clients.jedis.Client;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisClusterConnectionHandler;
import redis.clients.jedis.JedisClusterInfoCache;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisSlotBasedConnectionHandler;
import redis.clients.jedis.PipelineBase;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import redis.clients.jedis.exceptions.JedisRedirectionException;
import redis.clients.util.JedisClusterCRC16;
import redis.clients.util.SafeEncoder;

/**
 * @program: message
 * @description: JedisClusterPipeLine 因爲pipeline是不支持在集羣模式下使用的。所以繼承PipelineBase接口,重寫這個方法了。
 * @author: Irving Wei
 * @create: 2018-11-27 10:22
 **/
public class JedisClusterPipeline extends PipelineBase implements Closeable {
	private static final Logger LOGGER = LoggerFactory.getLogger(JedisClusterPipeline.class); 
	
	// 部分字段沒有對應的獲取方法,只能採用反射來做
	// 你也可以去繼承JedisCluster和JedisSlotBasedConnectionHandler來提供訪問接口
	private static final Field FIELD_CONNECTION_HANDLER;
	private static final Field FIELD_CACHE;
	static {
		FIELD_CONNECTION_HANDLER = getField(BinaryJedisCluster.class, "connectionHandler");
		FIELD_CACHE = getField(JedisClusterConnectionHandler.class, "cache");
	}
	private JedisSlotBasedConnectionHandler connectionHandler;
	private JedisClusterInfoCache clusterInfoCache;
	private Queue<Client> clients = new LinkedList<Client>();// 根據順序存儲每個命令對應的Client
	private Map<JedisPool, Jedis> jedisMap = new HashMap<>();// 用於緩存連接
	private boolean hasDataInBuf = false;// 是否有數據在緩存區
	
	/*
	 * 根據jedisCluster實例生成對應的JedisClusterPipeline*
	 * @param
	 * @return
	 */ 
	public static JedisClusterPipeline pipelined(JedisCluster jedisCluster) {
		JedisClusterPipeline pipeline = new JedisClusterPipeline();
		pipeline.setJedisCluster(jedisCluster);
		return pipeline;
	}

	public JedisClusterPipeline() {
	}

	public void setJedisCluster(JedisCluster jedis) {
		connectionHandler = getValue(jedis, FIELD_CONNECTION_HANDLER);
		clusterInfoCache = getValue(connectionHandler, FIELD_CACHE);
	}

	/**
	 * 刷新集羣信息,當集羣信息發生變更時調用
	 * 
	 * @param
	 * @return
	 */
	public void refreshCluster() {
		connectionHandler.renewSlotCache();
	}

	/**
	 * 同步讀取所有數據. 與syncAndReturnAll()相比,sync()只是沒有對數據做反序列化
	 */
	public void sync() {
		innerSync(null);
	}

	/**
	 * 同步讀取所有數據 並按命令順序返回一個列表
	 *
	 * @return 按照命令的順序返回所有的數據
	 */
	public List<Object> syncAndReturnAll() {
		List<Object> responseList = new ArrayList<Object>();
		innerSync(responseList);
		return responseList;
	}

	private void innerSync(List<Object> formatted) {
		HashSet<Client> clientSet = new HashSet<Client>();
		try {
			for (Client client : clients) {
				// 在sync()調用時其實是不需要解析結果數據的,但是如果不調用get方法,發生了JedisMovedDataException這樣的錯誤應用是不知道的,因此需要調用get()來觸發錯誤。
				// 其實如果Response的data屬性可以直接獲取,可以省掉解析數據的時間,然而它並沒有提供對應方法,要獲取data屬性就得用反射,不想再反射了,所以就這樣了
				Object data = generateResponse(client.getOne()).get();
				if (null != formatted) {
					formatted.add(data);
				}
				// size相同說明所有的client都已經添加,就不用再調用add方法了
				if (clientSet.size() != jedisMap.size()) {
					clientSet.add(client);
				}
			}
		} catch (JedisRedirectionException jre) {
			if (jre instanceof JedisMovedDataException) {
				// if MOVED redirection occurred, rebuilds cluster's slot cache,
				// recommended by Redis cluster specification
				refreshCluster();
			}
			throw jre;
		} finally {
			if (clientSet.size() != jedisMap.size()) {
				// 所有還沒有執行過的client要保證執行(flush),防止放回連接池後後面的命令被污染
				for (Jedis jedis : jedisMap.values()) {
					if (clientSet.contains(jedis.getClient())) {
						continue;
					}
					flushCachedData(jedis);
				}
			}
			hasDataInBuf = false;
			close();
		}
	}

	@Override
	public void close() {
		clean();
		clients.clear();
		for (Jedis jedis : jedisMap.values()) {
			if (hasDataInBuf) {
				flushCachedData(jedis);
			}
			jedis.close();
		}
		jedisMap.clear();
		hasDataInBuf = false;
	}

	private void flushCachedData(Jedis jedis) {
		try {
			jedis.getClient().getAll();
		} catch (RuntimeException ex) {

		}
	}

	@Override
	protected Client getClient(String key) {
		byte[] bKey = SafeEncoder.encode(key);
		return getClient(bKey);
	}

	@Override
	protected Client getClient(byte[] key) {
		Jedis jedis = getJedis(JedisClusterCRC16.getSlot(key));
		Client client = jedis.getClient();
		clients.add(client);
		return client;
	}

	private Jedis getJedis(int slot) {
		JedisPool pool = clusterInfoCache.getSlotPool(slot);
		// 根據pool從緩存中獲取Jedis
		Jedis jedis = jedisMap.get(pool);
		if (null == jedis) {
			jedis = pool.getResource();
			jedisMap.put(pool, jedis);
		}
		hasDataInBuf = true;
		return jedis;
	}

	private static Field getField(Class<?> cls, String fieldName) {
		try {
			Field field = cls.getDeclaredField(fieldName);
			field.setAccessible(true);
			return field;
		} catch (NoSuchFieldException | SecurityException e) {
			throw new RuntimeException("cannot find or access field '" + fieldName + "' from " + cls.getName(), e);
		}
	}

	@SuppressWarnings({ "unchecked" })
	private static <T> T getValue(Object obj, Field field) {
		try {
			return (T) field.get(obj);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			LOGGER.error("get value fail", e);
			throw new RuntimeException(e);
		}
	}

}
package org.atm.dc.app.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
@Primary
public class RedisClusterProperties {

	List<String> nodes;

	public List<String> getNodes() {
		return nodes;
	}

	public void setNodes(List<String> nodes) {
		this.nodes = nodes;
	}
}
package org.atm.dc.app.config;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching
@EnableConfigurationProperties(RedisClusterProperties.class)
public class RedisConfig extends CachingConfigurerSupport {

	

    @Autowired
    RedisClusterProperties clusterProperties;


    public @Bean
    RedisConnectionFactory connectionFactory() {
        return new JedisConnectionFactory(
                new RedisClusterConfiguration(clusterProperties.getNodes()));
    }
	/**
	 * 生成key的策略
	 * 
	 * @return
	 */
	@Bean
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
			@Override
			public Object generate(Object target, Method method, Object... params) {
				StringBuilder sb = new StringBuilder();
				sb.append(target.getClass().getName());
				sb.append(method.getName());
				for (Object obj : params) {
					sb.append(obj.toString());
				}
				return sb.toString();
			}
		};
	}

	@SuppressWarnings("rawtypes")
	@Bean
	public CacheManager cacheManager(RedisTemplate redisTemplate) {
		RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
		// 設置緩存過期時間
		// rcm.setDefaultExpiration(60);//秒
		return rcm;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Bean
	public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
		StringRedisTemplate template = new StringRedisTemplate(factory);
		Jackson2JsonRedisSerializer 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);
		// template.setValueSerializer(jackson2JsonRedisSerializer);
		template.afterPropertiesSet();
		return template;
	}
}
package org.atm.dc.app.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.atm.dc.app.config.RedisClusterProperties;
import org.atm.dc.utils.ApplicationContants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Response;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

@Service
public class RedisUtils {

	private Logger logger = LoggerFactory.getLogger(RedisUtils.class);
	@SuppressWarnings("rawtypes")
	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	RedisClusterProperties clusterProperties;

	/**
	 * 寫入緩存
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public boolean set(final String key, Object value) {
		boolean result = false;
		try {
			ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 寫入緩存設置時效時間
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
		boolean result = false;
		try {
			ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			redisTemplate.expire(key, expireTime, timeUnit);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> hgetAll(String key) {
		Map<String, Object> hgetAll = redisTemplate.opsForHash().entries(key);
		return hgetAll;
	}

	/**
	 * 批量刪除對應的value
	 *
	 * @param keys
	 */
	public void remove(final String... keys) {
		for (String key : keys) {
			remove(key);
		}
	}

	/**
	 * 批量刪除key
	 *
	 * @param pattern
	 */
	@SuppressWarnings("unchecked")
	public void removePattern(final String pattern) {
		Set<Serializable> keys = redisTemplate.keys(pattern);
		if (keys.size() > 0) {
			redisTemplate.delete(keys);
		}
	}

	/**
	 * 刪除對應的value
	 *
	 * @param key
	 */
	@SuppressWarnings("unchecked")
	public void remove(final String key) {
		if (exists(key)) {
			redisTemplate.delete(key);
		}
	}

	/**
	 * 判斷緩存中是否有對應的value
	 *
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public boolean exists(final String key) {
		return redisTemplate.hasKey(key);
	}

	/**
	 * 讀取緩存
	 *
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Object get(final String key) {
		Object result = null;
		ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
		result = operations.get(key);
		return result;
	}

	/**
	 * 模糊匹配key,讀取所有符合條件的數據
	 * @param key
	 * @return List<Object>
	 */
	@SuppressWarnings({ "unchecked" })
	public List<Object> getRedis2(String key) {
		List<Object> list = new ArrayList<Object>();
		try {
			Set<String> keys = redisTemplate.keys("*" + key + "*");
			list = redisTemplate.opsForValue().multiGet(keys);
		} catch (Exception e) {
			logger.info("getRedis2,報錯太頻繁,所以簡寫。可能是這個錯誤:java.net.SocketTimeoutException: Read timed out");
		}
		return list;
	}
	/**
	 * 模糊匹配key,讀取所有符合條件的數據【查詢一次大約10ms,查詢一萬次需要10s,不建議使用此方法】
	 * @param key
	 * @return Map<String, Object>
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> getRedis(final String key) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			Set<String> keys = redisTemplate.keys("*" + key + "*");
			for (String string : keys) {
				Object value = redisTemplate.opsForValue().get(string);
				map.put(string, value);
			}
		} catch (Exception e) {
			logger.info("getRedis,報錯太頻繁,所以簡寫。可能是這個錯誤:java.net.SocketTimeoutException: Read timed out");
		}
		return map;
	}
	/**
	 * 模糊匹配key,讀取所有符合條件的數據【查詢一次大約10ms,查詢一萬次需要10s,不建議使用此方法】
	 * @param key
	 * @return hash類型
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Map<Object, Object>> getRedisHash(final String key) {
		Map<String, Map<Object, Object>> map = new HashMap<String, Map<Object, Object>>();
		Set<String> keys = redisTemplate.keys("*" + key + "*");
		for (String string : keys) {
			HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
			Map<Object, Object> value = hash.entries(string);
			map.put(string, value);
		}
		return map;
	}
	/**
	 * 模糊匹配key,讀取所有符合條件的數據【】
	 * @param key
	 * @return Map<String, List<Object>>
	 */
	@SuppressWarnings("unchecked")
	public Map<String, List<Object>> getRedisList(final String key) {
		Map<String, List<Object>> map = new HashMap<String, List<Object>>();
		try {
			Set<String> keys = redisTemplate.keys("*" + key + "*");
			for (String string : keys) {
				List<Object> list = lRange(string, 0, -1);
				map.put(string, list);
			}
		} catch (Exception e) {
			logger.info("getRedisList,報錯太頻繁,所以簡寫。可能是這個錯誤:java.net.SocketTimeoutException: Read timed out");
		}
		return map;
	}

	/**
	 * 哈希 添加
	 *
	 * @param key
	 * @param hashKey
	 * @param value
	 */
	@SuppressWarnings("unchecked")
	public void hmSet(String key, Object hashKey, Object value) {
		HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();

		hash.put(key, hashKey, value);
	}

	/**
	 * 哈希獲取數據
	 *
	 * @param key
	 * @param hashKey
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Object hmGet(String key, Object hashKey) {
		HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
		return hash.get(key, hashKey);
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> hmEntries(String key) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.entries(key);
	}

	/**
	 * 列表添加
	 *
	 * @param k
	 * @param v
	 */
	@SuppressWarnings("unchecked")
	public void lPush(String k, Object v) {
		ListOperations<String, Object> list = redisTemplate.opsForList();
		list.rightPush(k, v);
	}

	/**
	 * 列表獲取
	 *
	 * @param k
	 * @param l
	 * @param l1
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Object> lRange(String k, long l, long l1) {
		ListOperations<String, Object> list = redisTemplate.opsForList();
		return list.range(k, l, l1);
	}

	/**
	 * 集合添加
	 *
	 * @param key
	 * @param value
	 */
	@SuppressWarnings("unchecked")
	public void add(String key, Object value) {
		SetOperations<String, Object> set = redisTemplate.opsForSet();
		set.add(key, value);
	}

	/**
	 * 集合獲取
	 *
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Set<Object> setMembers(String key) {
		SetOperations<String, Object> set = redisTemplate.opsForSet();
		return set.members(key);
	}

	/**
	 * 有序集合添加
	 *
	 * @param key
	 * @param value
	 * @param scoure
	 */
	@SuppressWarnings("unchecked")
	public void zAdd(String key, Object value, double scoure) {
		ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
		zset.add(key, value, scoure);
	}

	/**
	 * 有序集合獲取
	 *
	 * @param key
	 * @param scoure
	 * @param scoure1
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
		ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
		return zset.rangeByScore(key, scoure, scoure1);
	}

	/**
	 * pipeline獲取數據。Set集合
	 * @param str
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Set<String>> usePipeline2(String str) {
		Map<String, Set<String>> result = new HashMap<String, Set<String>>();
		JedisCluster jedis = getJedisCluster();
		JedisClusterPipeline pipeline = null;
		try {
//			long aa = System.currentTimeMillis();
			Map<String, Response<Set<String>>> responses = new HashMap<String, Response<Set<String>>>();
			Set<String> keys = redisTemplate.keys("*" + str + "*");
//			long bb = System.currentTimeMillis();

			pipeline = JedisClusterPipeline.pipelined(jedis);
			for(String key : keys) {
				responses.put(key, pipeline.smembers(key));
			}
			long cc = System.currentTimeMillis();
			pipeline.sync();
			long dd = System.currentTimeMillis();
			logger.info("responses.size()-----" + responses.size() + ",pipeline.sync()------" + (dd - cc) + "ms");
			for(String k : responses.keySet()) {
				result.put(k, responses.get(k).get());
			}
//			long ee = System.currentTimeMillis();
		} catch (Exception e) {
			logger.info("usePipeline2,報錯太頻繁,所以簡寫。可能是這個錯誤:java.net.SocketTimeoutException: Read timed out");
		}finally {
			pipeline.close();
		}
		return result;
	}
	/**
	 * pipeline獲取數據。List集合
	 * @param str
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Map<String, List<String>> usePipeline(String str) {
		Map<String, List<String>> result = new HashMap<String, List<String>>();
		JedisCluster jedis = getJedisCluster();
		JedisClusterPipeline pipeline = null;
		try {
//			long aa = System.currentTimeMillis();
			Map<String, Response<List<String>>> responses = new HashMap<String, Response<List<String>>>();
			Set<String> keys = redisTemplate.keys("*" + str + "*");
//			long bb = System.currentTimeMillis();
//			System.out.println("redisTemplate.keys------" + (bb - aa) + "ms");

			pipeline = JedisClusterPipeline.pipelined(jedis);
			for(String key : keys) {
				responses.put(key, pipeline.lrange(key, 0, -1));
			}
			long cc = System.currentTimeMillis();
//			System.out.println("pipeline.lrange------" + (cc - bb) + "ms");
			pipeline.sync();
			long dd = System.currentTimeMillis();
			logger.info("responses.size()-----" + responses.size() + ",pipeline.sync()------" + (dd - cc) + "ms");
			for(String k : responses.keySet()) {
				result.put(k, responses.get(k).get());
			}
//			long ee = System.currentTimeMillis();
//			System.out.println("result.put------" + (ee - dd) + "ms");
		} catch (Exception e) {
			logger.info("usePipeline,報錯太頻繁,所以簡寫。可能是這個錯誤:java.net.SocketTimeoutException: Read timed out");
		}finally {
			pipeline.close();
		}
		return result;
	}

	/**
	 * 集羣
	 * @return
	 */
	private JedisCluster getJedisCluster() {
		// 添加集羣的服務節點Set集合
		Set<HostAndPort> hostAndPortsSet = new HashSet<HostAndPort>();
		// 添加節點
		String[] arr = null;
		List<String> list = clusterProperties.getNodes();
		for (String string : list) {
			arr = string.split(":");
			hostAndPortsSet.add(new HostAndPort(arr[0], Integer.parseInt(arr[1])));
		}
		// Jedis連接池配置
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		// 最大空閒連接數, 默認8個
		jedisPoolConfig.setMaxIdle(100);
		// 最大連接數, 默認8個
		jedisPoolConfig.setMaxTotal(500);
		//最小空閒連接數, 默認0
		jedisPoolConfig.setMinIdle(0);
		// 獲取連接時的最大等待毫秒數(如果設置爲阻塞時BlockWhenExhausted),如果超時就拋異常, 小於零:阻塞不確定的時間,  默認-1
		jedisPoolConfig.setMaxWaitMillis(2000); // 設置2秒
		//對拿到的connection進行validateObject校驗
		jedisPoolConfig.setTestOnBorrow(true);
		JedisCluster jedis = new JedisCluster(hostAndPortsSet, jedisPoolConfig);
		return jedis;
	}

	/**
	 * 單節點、非集羣
	 * @return
	 */
	@SuppressWarnings("resource")
	public ShardedJedis getShardedJedis() {
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxTotal(2);
		poolConfig.setMaxIdle(1);
		poolConfig.setMaxWaitMillis(2000);
		poolConfig.setTestOnBorrow(false);
		poolConfig.setTestOnReturn(false);
		JedisShardInfo info1 = new JedisShardInfo(ApplicationContants.redisHost, ApplicationContants.redisPort);
		info1.setSoTimeout(3000);
		info1.setPassword(ApplicationContants.redisPwd);//這裏是密碼
		JedisShardInfo info2 = new JedisShardInfo(ApplicationContants.redisHost, ApplicationContants.redisPort);
		info2.setSoTimeout(3000);
		info2.setPassword(ApplicationContants.redisPwd);//這裏是密碼
		ShardedJedisPool pool = new ShardedJedisPool(poolConfig, Arrays.asList(info1, info2));
		return pool.getResource();
	}


}

2.備註

<!--集成redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>1.4.1.RELEASE</version>
</dependency>


報錯可以註釋掉RedisConfig.java
//	@SuppressWarnings("rawtypes")
//	@Bean
//	public CacheManager cacheManager(RedisTemplate redisTemplate) {
//		RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//		// 設置緩存過期時間
//		// rcm.setDefaultExpiration(60);//秒
//		return rcm;
//	}


後綴爲:.properties
spring.redis.cluster.nodes=IP1:6379,IP2:6379,IP3:6379
spring.redis.password=




後綴爲:.yml
spring:
  redis:
    cluster:
      nodes:  IP1:6379,IP2:6379,IP3:6379
    password:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章