四、哨兵(Sentinel)模式
1、哨兵是什么能干嘛?
2、哨兵(Sentinel)模式原理


3、搭建1主2从3个哨兵

3.1、创建3个sentinel配置文件
cd /opt/redis-stable/config/touch sentinel-26379.confvi sentinel-26379.conf
bind 0.0.0.0# 配置文件目录dir /opt/redis-stable/config/# 日志文件位置logfile "./sentinel-26379.log"# pid文件pidfile /var/run/sentinel_26379.pid# 是否后台运行daemonize yes# 端口port 26379# 监控主服务器master的名字:mymaster,IP:127.0.0.1,port:6379,最后的数字2表示当Sentinel集群中有2个Sentinel认为master存在故障不可用,则进行自动故障转移sentinel monitor mymaster 127.0.0.1 6379 2# master响应超时时间(毫秒),Sentinel会向master发送ping来确认master,如果在20秒内,ping不通master,则主观认为master不可用sentinel down-after-milliseconds mymaster 20000# 故障转移超时时间(毫秒),如果3分钟内没有完成故障转移操作,则视为转移失败sentinel failover-timeout mymaster 180000# 故障转移之后,进行新的主从复制,配置项指定了最多有多少个slave对新的master进行同步,那可以理解为1是串行复制,大于1是并行复制sentinel parallel-syncs mymaster 1# 指定mymaster主的密码(没有就不指定)sentinel auth-pass mymaster 123456
(2)创建sentinel2的配置文件:sentinel-26380.conf
touch sentinel-26380.confvi sentinel-26380.conf
bind 0.0.0.0# 配置文件目录dir /opt/redis-stable/config/# 日志文件位置logfile "./sentinel-26380.log"# pid文件pidfile /var/run/sentinel_26380.pid# 是否后台运行daemonize yes# 端口port 26380# 监控主服务器master的名字:mymaster,IP:127.0.0.1,port:6379,最后的数字2表示当Sentinel集群中有2个Sentinel认为master存在故障不可用,则进行自动故障转移sentinel monitor mymaster 127.0.0.1 6379 2# master响应超时时间(毫秒),Sentinel会向master发送ping来确认master,如果在20秒内,ping不通master,则主观认为master不可用sentinel down-after-milliseconds mymaster 20000# 故障转移超时时间(毫秒),如果3分钟内没有完成故障转移操作,则视为转移失败sentinel failover-timeout mymaster 180000# 故障转移之后,进行新的主从复制,配置项指定了最多有多少个slave对新的master进行同步,那可以理解为1是串行复制,大于1是并行复制sentinel parallel-syncs mymaster 1# 指定mymaster主的密码(没有就不指定)sentinel auth-pass mymaster 123456
(3)创建sentinel3的配置文件:sentinel-26381.conf
touch sentinel-26381.confvi sentinel-26381.conf
bind 0.0.0.0# 配置文件目录dir /opt/redis-stable/config/# 日志文件位置logfile "./sentinel-26381.log"# pid文件pidfile /var/run/sentinel_26381.pid# 是否后台运行daemonize yes# 端口port 26381# 监控主服务器master的名字:mymaster,IP:127.0.0.1,port:6379,最后的数字2表示当Sentinel集群中有2个Sentinel认为master存在故障不可用,则进行自动故障转移sentinel monitor mymaster 127.0.0.1 6379 2# master响应超时时间(毫秒),Sentinel会向master发送ping来确认master,如果在20秒内,ping不通master,则主观认为master不可用sentinel down-after-milliseconds mymaster 20000# 故障转移超时时间(毫秒),如果3分钟内没有完成故障转移操作,则视为转移失败sentinel failover-timeout mymaster 180000# 故障转移之后,进行新的主从复制,配置项指定了最多有多少个slave对新的master进行同步,那可以理解为1是串行复制,大于1是并行复制sentinel parallel-syncs mymaster 1# 指定mymaster主的密码(没有就不指定)sentinel auth-pass mymaster 123456
3.2、启动3个sentinel
/opt/redis-stable/src/redis-sentinel opt/redis-stable/config/sentinel-26379.conf/opt/redis-stable/src/redis-sentinel opt/redis-stable/config/sentinel-26380.conf/opt/redis-stable/src/redis-sentinel /opt/redis-stable/config/sentinel-26381.conf

3.3、使用Redis DeskTop连接sentinel

3.4、验证故障自动转移是否成功



127.0.0.1:6381>set address chinaOK
3.4、恢复旧的master自动俯首称臣

4、Sentinel支持的命令
五、Jedis连接Sentinel模式
import redis.clients.jedis.HostAndPort;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.JedisSentinelPool;import java.util.HashSet;import java.util.Set;public class SentinelDemo {private static JedisSentinelPool jedisSentinelPool;static {try {JedisPoolConfig config = new JedisPoolConfig();//最大空闲连接数, 默认8个config.setMaxIdle(8);//最大连接数, 默认8个config.setMaxTotal(8);//最小空闲连接数, 默认0config.setMinIdle(0);//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1config.setMaxWaitMillis(3000);//在获取连接的时候检查有效性,表示取出的redis对象可用, 默认falseconfig.setTestOnBorrow(true);//redis服务器列表Set<String> sentinels = new HashSet<>();sentinels.add(new HostAndPort("192.168.115.78", 26379).toString());sentinels.add(new HostAndPort("192.168.115.78", 26380).toString());sentinels.add(new HostAndPort("192.168.115.78", 26381).toString());//初始化连接池jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, config, "123456");} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {// 从池中获取一个Jedis对象Jedis jedis = jedisSentinelPool.getResource();String aaa = jedis.get("aaa");System.out.println(aaa);jedis.close();}}
六、SpringBoot整合Sentinel模式
@Autowiredprivate RedisTemplate<String, String> redisTemplate;// 用下面5个对象来操作对应的类型this.redisTemplate.opsForValue(); //提供了操作string类型的所有方法this.redisTemplate.opsForList(); // 提供了操作list类型的所有方法this.redisTemplate.opsForSet(); //提供了操作set的所有方法this.redisTemplate.opsForHash(); //提供了操作hash表的所有方法this.redisTemplate.opsForZSet(); //提供了操作zset的所有方法
@RestController@RequestMapping("/redis")public class RedisController {@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** string测试** @return*/@RequestMapping("/stringTest")public String stringTest() {this.redisTemplate.delete("name");this.redisTemplate.opsForValue().set("name", "路人");String name = this.redisTemplate.opsForValue().get("name");return name;}/*** list测试** @return*/@RequestMapping("/listTest")public List<String> listTest() {this.redisTemplate.delete("names");this.redisTemplate.opsForList().rightPushAll("names", "刘德华", "张学友","郭富城", "黎明");List<String> courses = this.redisTemplate.opsForList().range("names", 0,-1);return courses;}/*** set类型测试** @return*/@RequestMapping("setTest")public Set<String> setTest() {this.redisTemplate.delete("courses");this.redisTemplate.opsForSet().add("courses", "java", "spring","springboot");Set<String> courses = this.redisTemplate.opsForSet().members("courses");return courses;}/*** hash表测试** @return*/@RequestMapping("hashTest")public Map<Object, Object> hashTest() {this.redisTemplate.delete("userMap");Map<String, String> map = new HashMap<>();map.put("name", "路人");map.put("age", "30");this.redisTemplate.opsForHash().putAll("userMap", map);Map<Object, Object> userMap =this.redisTemplate.opsForHash().entries("userMap");return userMap;}/*** zset测试** @return*/@RequestMapping("zsetTest")public Set<String> zsetTest() {this.redisTemplate.delete("languages");this.redisTemplate.opsForZSet().add("languages", "java", 100d);this.redisTemplate.opsForZSet().add("languages", "c", 95d);this.redisTemplate.opsForZSet().add("languages", "php", 70);Set<String> languages =this.redisTemplate.opsForZSet().range("languages", 0, -1);return languages;}/*** 查看redis机器信息** @return*/@RequestMapping(value = "/info", produces = MediaType.TEXT_PLAIN_VALUE)public String info() {Object obj = this.redisTemplate.execute(new RedisCallback<Object>() {@Overridepublic Object doInRedis(RedisConnection connection) throwsDataAccessException {return connection.execute("info");}});return obj.toString();}
版权声明:本文内容始发于CSDN>作者:怪 咖@,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。始发链接:https://blog.csdn.net/weixin_43888891/article/details/131039418在此特别鸣谢原作者的创作。此篇文章的所有版权归原作者所有,商业转载建议请联系原作者,非商业转载请注明出

文章转载自巴韭特锁螺丝,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





