一、集羣部署 這裏就不詳細贅述如何部署主從集羣了,通常都是使用slaveOf配置來進行初始化配置。redis
二、與springboot集成實現讀寫分離 經過註解實現調用層讀寫分離,而後根據取模運算來肯定訪問哪一個讀庫spring
配置讀寫節點springboot
spring: redis: database: 0 pool: max-active: 8 max-idle: 9 max-wait: -1 min-idle: 0 redis-master: host: 192.168.1.1 prot: 6379 password: testOnBorrow: false redis-slave1: host: 192.168.1.2 prot: 6379 password: testOnBorrow: false redis-slave2: host: 192.168.1.3 prot: 6379 password: testOnBorrow: false
以下:code
@Configuration public class RedisConfiguration { @Value("${spring.redis.pool.max-idle}") private int maxIdle; @Value("${spring.redis.pool.max-active}") private int maxTotal; @Value("${spring.redis.database}") private int index; @Value("${spring.redis.pool.max-wait}") private long maxWaitMillis; @Bean(name = "redisMasterTemplate") public StringRedisTemplate redisMasterTemplate(@Value("${spring.redis-master.host}") String hostName, @Value("${spring.redis-master.port}") int port, @Value("${spring.redis-master.password}") String password, @Value("${spring.redis-master.testOnBorrow}") boolean testOnBorrow) { StringRedisTemplate temple = new StringRedisTemplate(); temple.setConnectionFactory( connectionFactory(hostName, port, password, maxIdle, maxTotal, index, maxWaitMillis, testOnBorrow)); return temple; } @Bean(name = "redisSlave1Template") public StringRedisTemplate redisSlave1Template(@Value("${spring.redis-slave1.host}") String hostName, @Value("${spring.redis-slave1.port}") int port, @Value("${spring.redis-slave1.password}") String password, @Value("${spring.redis-slave1.testOnBorrow}") boolean testOnBorrow) { StringRedisTemplate temple = new StringRedisTemplate(); temple.setConnectionFactory( connectionFactory(hostName, port, password, maxIdle, maxTotal, index, maxWaitMillis, testOnBorrow)); return temple; } @Bean(name = "redisSlave1Template") public List<StringRedisTemplate> redisSlaveTemplate() { List<StringRedisTemplate> list = new ArrayList<StringRedisTemplate>(); list.add(redisSlave1Template()); list.add(redisSlave2Template()); return list; } @Bean(name = "redisSlave2Template") public StringRedisTemplate redisSlave1Template(@Value("${spring.redis-slave2.host}") String hostName, @Value("${spring.redis-slave2.port}") int port, @Value("${spring.redis-slave2.password}") String password, @Value("${spring.redis-slave2.testOnBorrow}") boolean testOnBorrow) { StringRedisTemplate temple = new StringRedisTemplate(); temple.setConnectionFactory( connectionFactory(hostName, port, password, maxIdle, maxTotal, index, maxWaitMillis, testOnBorrow)); return temple; } public RedisConnectionFactory connectionFactory(String hostName, int port, String password, int maxIdle, int maxTotal, int index, long maxWaitMillis, boolean testOnBorrow) { JedisConnectionFactory jedis = new JedisConnectionFactory(); jedis.setHostName(hostName); jedis.setPort(port); if (StringUtils.isNotEmpty(password)) { jedis.setPassword(password); } if (index != 0) { jedis.setDatabase(index); } jedis.setPoolConfig(poolCofig(maxIdle, maxTotal, maxWaitMillis, testOnBorrow)); // 初始化鏈接pool jedis.afterPropertiesSet(); RedisConnectionFactory factory = jedis; return factory; } public JedisPoolConfig poolCofig(int maxIdle, int maxTotal, long maxWaitMillis, boolean testOnBorrow) { JedisPoolConfig poolCofig = new JedisPoolConfig(); poolCofig.setMaxIdle(maxIdle); poolCofig.setMaxTotal(maxTotal); poolCofig.setMaxWaitMillis(maxWaitMillis); poolCofig.setTestOnBorrow(testOnBorrow); return poolCofig; } }
封裝調用接口接口
@Component public class StringRedisTemplateProxy { @Autowired private StringRedisTemplate redisMasterTemplate; @Autowired private List<StringRedisTemplate> redisSlaveList; private int index=0; public void setValue(String key,String value) { redisMasterTemplate.opsForValue().set(key, value); } public String getValue(String key) { index++; return redisSlaveList.get(index).opsForValue().get(key); } }
這裏缺點就是沒法作到故障轉移,這裏就須要用到虛擬ip和腳本定時監控。 一、使用一個虛擬ip指向redis master 二、若是從節點故障,能夠採用重試機制來進行一次調用讀節點,若是是主節點故障,則須要經過腳本自動將一個從節點切換成主節點,並將虛擬IP綁定在該節點上。ip