1. 哨兵机构原理
client 客户端第一次从哨兵集群获取到主节点信息后,就将主节点信息保存在本地,下次就直接访问 Redis 主节点。当 redis 集群主节点宕机,哨兵会从新选举主节点,并通知客户端(经过订阅功能实现)。java
2. 哨兵架构搭建
修改 sentinel.conf 配置文件node
port 26379 # 若是是在同一台机器上启动多台sentinel服务,注意修改端口号 daemonize yes # 后台启动 # sentinel monitor <master‐name> <ip> <redis‐port> <quorum> 11 # quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值通常为:sentinel总数/2 + 1),master才算真正失效 # 注意ip不能使用 127.0.0.1 sentinel monitor mymaster 192.168.137.20 6379 2 ============================== 启动哨兵实例命令: src/redis‐sentinel sentinel.conf 查看sentinel的info信息,输入info能够查看主从以及哨兵信息 src/redis-cli -p 26379 ->info
3. Jedis 链接哨兵
Java 代码web
package com.zg.jedis; import redis.clients.jedis.*; import java.util.HashSet; import java.util.Set; /** * jedis 链接redis哨兵模式 * * @author zg * @date 2020/9/12 */ public class JedisSentinelTest { public static void main(String[] args) { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(20); config.setMaxIdle(10); config.setMinIdle(5); String masterName = "mymaster"; Set<String> sentinels = new HashSet<>(); sentinels.add(new HostAndPort("192.168.137.20", 26379).toString()); sentinels.add(new HostAndPort("192.168.137.20", 26380).toString()); sentinels.add(new HostAndPort("192.168.137.20", 26381).toString()); JedisSentinelPool jedisSentinelPool = null; Jedis jedis = null; try { jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config, 3000, null); jedis = jedisSentinelPool.getResource(); System.out.println(jedis.set("sentinel_test", "321")); System.out.println(jedis.get("sentinel_test")); } catch (Exception e) { e.printStackTrace(); } finally { if (null != jedis) { jedis.close(); } if (null != jedisSentinelPool) { jedisSentinelPool.close(); } } } }
4. Springboot 链接哨兵架构
pom 依赖redis
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
application.properties 配置文件:spring
spring.redis.database=0 spring.redis.timeout=3000ms spring.redis.lettuce.pool.max-idle=50 spring.redis.lettuce.pool.min-idle=10 spring.redis.lettuce.pool.max-active=100 spring.redis.lettuce.pool.max-wait=1000ms spring.redis.sentinel.master=mymaster spring.redis.sentinel.nodes=192.168.137.20:26379,192.168.137.20:26380,192.168.137.20:26381
java 代码 apache
package com.zg.redis.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 哨兵架构测试 * 启动方法后程序正常运行, * 关闭主节点后程序报错, * 一段时间后能够看到程序恢复运行, * 查看sentinel已经从新选取主节点 * @author zg * @date 2020/9/12 */ @RestController public class RedisController { @Autowired private StringRedisTemplate stringRedisTemplate; @RequestMapping("test") public String test(){ return "success"; } @RequestMapping("testSentinel") public void testSentinel(){ int i = 1; while (true){ try { stringRedisTemplate.opsForValue().set("key_" + i, "value_" + i); System.out.println("设置key:key_" + i); i++; Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } } } }
5. 哨兵架构存在的问题
1. master主节点宕机后,从新选举存在一段时间不可访问
2. 只有一个主节点,最高支持 QPS 十万,在更高的并发下将不可用。
3. redis 节点内存通常设置为 4G (更高的话,会影响启动和数据同步的时间),所以只有一个主节点的话,redis缓存容量有限缓存