本文为博主原创,未经允许不得转载:
目录:
1. 哨兵 Sentinel 介绍
2. 哨兵架构特点及工作原理
3. redis哨兵架构搭建步骤
4. 哨兵数据丢失
5. spring boot 整合 哨兵
1. 哨兵 Sentinel 介绍:
sentinel,中文名是哨兵。主要有以下功能:
- 集群监控:负责监控 Redis master 和 slave 进程是否正常工作。
- 消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
- 故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
- 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
哨兵用于实现 Redis 集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。
2. 哨兵架构特点及工作原理:
- 哨兵至少需要 3 个实例,来保证自己的健壮性。
- 哨兵 + Redis 主从的部署架构,是不保证数据零丢失的,只能保证 Redis 集群的高可用性。
sentinel 工作原理:
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)
3. redis哨兵架构搭建步骤:
1、复制一份sentinel.conf文件
cp sentinel.conf sentinel-26379.conf
2、修改配置:
port 26379 daemonize yes pidfile "/var/run/redis-sentinel-26379.pid" logfile "26379.log" dir "/usr/local/redis-5.0.3/data" # sentinel monitor <master-redis-name> <master-redis-ip> <master-redis-port> <quorum> # quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效 sentinel monitor mymaster 112.125.26.68 6379 2 # mymaster这个名字随便取,客户端访问时会用到
3、启动sentinel哨兵实例
src/redis-sentinel sentinel-26379.conf
4、查看sentinel的info信息:可以看到Sentinel的info里已经识别出了redis的主从
src/redis-cli -p 26379 127.0.0.1:26379>info
5、再配置两个sentinel,端口26380和26381,注意上述配置文件里的对应数字都要修改
sentinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的最下面),可配置文件sentinel-26379.conf,如下所示:
sentinel known-replica mymaster 112.125.26.68 6380 #代表redis主节点的从节点信息 sentinel known-replica mymaster 112.125.26.68 6381 #代表redis主节点的从节点信息 sentinel known-sentinel mymaster 112.125.26.68 26380 52d0a5d70c1f90475b4fc03b6ce7c3c56935760f #代表感知到的其它哨兵节点 sentinel known-sentinel mymaster 112.125.26.68 26381 e9f530d3882f8043f76ebb8e1686438ba8bd5ca6 #代表感知到的其它哨兵节点
4. 哨兵数据丢失:
存在以下两种数据丢失场景:
1. 异步复制导致的数据丢失
因为 master->slave 的复制是异步的,所以可能有部分数据还没复制到 slave,master 就宕机了,此时这部分数据就丢失了。
2. 脑裂导致的数据丢失
某个 master 所在机器突然脱离了正常的网络,跟其他 slave 机器不能连接,但是实际上 master 还运行着。此时哨兵可能就会认为 master 宕机了,然后开启选举,将其他 slave 切换成了 master。这个时候,集群里就会有两个 master ,也就是所谓的脑裂。
此时虽然某个 slave 被切换成了 master,但是可能 client 还没来得及切换到新的 master,还继续向旧 master 写数据。因此旧 master 再次恢复的时候,会被作为一个 slave 挂到新的 master 上去,自己的数据会清空,重新从新的 master 复制数据。而新的 master 并没有后来 client 写入的数据,因此,这部分数据也就丢失了。
解决方案:
要求至少有 1 个 slave,数据复制和同步的延迟不能超过 10 秒。
5. spring boot 整合 哨兵:
1、引入相关依赖:
<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>
2. 配置
server: port: 8080 spring: redis: database: 0 timeout: 3000 sentinel: #哨兵模式 master: mymaster #主服务器所在集群名称 nodes: 192.168.0.60:26379,192.168.0.60:26380,192.168.0.60:26381 lettuce: pool: max-idle: 50 min-idle: 10 max-active: 100 max-wait: 1000
3. 访问代码
@RestController public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @Autowired private StringRedisTemplate stringRedisTemplate; /** * 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到 * 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制, * 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的masterip * * @throws InterruptedException */ @RequestMapping("/test_sentinel") public void testSentinel() throws InterruptedException { int i = 1; while (true){ try { stringRedisTemplate.opsForValue().set("test"+i, i+""); System.out.println("设置key:"+ "test" + i); i++; Thread.sleep(1000); }catch (Exception e){ logger.error("错误:", e); } } } }
标签: redis