一、集群部署 这里就不详细赘述如何部署主从集群了,通常都是使用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