每天多学一点点~
话不多说,这就开始吧…
之前搭建了redis的主从架构(一主两从),今天再优化一下,来学习下Redis的哨兵高可用架构。
Redis系列文章
主从模式
最初的redis架构模式,主写从读,为了防止服务器挂了(硬盘坏了)的情况下数据丢失,且不存在选举,若主服务器挂了,必须重写启动从服务器,改其配置让其成为主(当然可以写脚本,虽然现在基本上不怎么用了)。
哨兵模式
在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会 做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,且单个主节点 内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率
高可用集群
redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需要 sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可 水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的性能和高可用性均优于 之前版本的哨兵模式,且集群配置非常简单
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。 哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过 sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis 主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)
之前已经搭建过了redis主从(1主2从),在次基础上搭建哨兵
Redis主从架构搭建以及主从复制原理
192.168.73.130:26380 192.168.73.130:26381 192.168.73.130:26382
建立三个文件夹 26380 26381 26382,将 sentinel.conf文件复制到其中对应的文件夹中,并改名 sentinel‐端口号.conf文件。
port 26380 # redis端口
daemonize yes #后台启动
protected-mode no #关闭自我保护
pidfile /var/run/redis‐sentinel‐26380.pid #redis进程文件id
logfile "26380.log" #redis日志文件
dir /usr/local/redis5.0.2/shaobin/data/26380 # redis日志文件目录
# sentinel monitor
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效,博主这里准备搭建三个哨兵,所以写2
sentinel monitor mymaster 192.168.73.130 6380 2 #指定redis主从的主节点(之前搭建的主节点ip)
# 每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过指定时间(默认30000ms)且没有回复,则判定不可达
sentinel down-after-milliseconds mymaster 1500
# 当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
src/redis-sentinel /usr/local/redis5.0.2/shaobin/26380/sentinel-26380.conf
src/redis-sentinel /usr/local/redis5.0.2/shaobin/26381/sentinel-26381.conf
src/redis-sentinel /usr/local/redis5.0.2/shaobin/26382/sentinel-26382.conf
redis-cli -p 26739
info sentinel # 查看sentinel的info信息
sentinel get-master-addr-by-name mymaster # 查看当前master
sentinel slaves mymaster # 查看监控的slaves节点
观察最后一行,可以看出,该sentinel节点监控的包括一个master节点(名为mymaster,该名字是之前在sentinel-*中定义的别名)和2个slave节点(slaves=2);而最后的sentinels=2则代表一共启动了3个sentinel节点对master slave节点进行监控。
之前sringboot整合redis时候,大多数西奥伙伴可能选用的是jedis连接池,但在这里博主选springboot自带的用lettuce连接池。
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
spring:
application:
name: redistest
redis:
database: 0
timeout: 3000 #超时时间
lettuce: # 这里标明使用lettuce配置
pool:
max‐idle: 50 # 连接池中的最大空闲连接
min‐idle: 10 # 连接池中的最小空闲连接
max‐active: 100 # 连接池最大连接数(使用负值表示没有限制)
max‐wait: 1000 # 连接池最大阻塞等待时间(使用负值表示没有限制)
sentinel:
master: mymaster #主服务器所在集群名称
nodes: 192.168.73.130:26380,192.168.73.130:26381,192.168.73.130:26382
/**
* redis序列化配置
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate
/**
* redis 哨兵模式 测试
*/
@RestController
public class RedisTestController {
private static Logger logger = LoggerFactory.getLogger(RedisTestController.class);
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到
* 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,
* 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的masterip
*/
@GetMapping("test_sentinel")
public void testSentinel() throws InterruptedException {
while (true) {
int i = 1;
redisTemplate.opsForValue().set("zjq" + i, i);
System.out.println("设置key:" + "zjq" + i);
i++;
Thread.sleep(1000);
}
}
}
现在将sentinel()
现在将6380(主)节点kill掉,观察哨兵集群的变化
代码开始报错,连接不上6380,等过了一会,哨兵集群选举成功之后,又继续开始运行代码了。我们在看下现在的主节点是谁。
6382变成了主节点。
再把6380启动,主节点依然是6382,且数据已经同步~
dbsize # 查看db里面key的个数
当一个master服务器被某sentinel视为客观下线状态后,该sentinel会与其他sentinel协商选出sentinel的leader进行故障转移工作。每个发现master服务器进入客观下线的sentinel都可以要求其他sentinel选自己为sentinel的leader,选举是先到先得。同时每个sentinel每次选举都会自增配置纪元(选举周期),每个纪元中只会选择一个sentinel的leader。如果所有超过一半的sentinel选举某sentinel作为leader。之后该sentinel进行故障转移操作,从存活的slave中选举出新的master,这个选举过程跟集群的master选举很类似。 哨兵集群只有一个哨兵节点,redis的主从也能正常运行以及选举master,如果master挂了,那唯一的那个哨兵节点就是哨兵leader了,可以正常选举新master。 不过为了高可用一般都推荐至少部署三个哨兵节点。为什么推荐奇数个哨兵节点原理跟集群奇数个master节点类似。
世上无难事,只怕有心人,每天积累一点点,fighting!!!