redis读写分离 -- 主从架构
- slave启动后,ping通master节点。master节点给slave一个数据复制任务,RDB全量数据同步。slave先将rdb文件下载到本地磁盘再读取; ----- 全量复制
- master将修改的执行命令赋值给slave,进行数据的持续同步。slave会在替换完成后再使用新的数据,没有同步完成之前读取时使用老的数据; ----- 增量传递
备注:master须开启持久化,否则master挂掉重启后不能恢复数据,slave会因为同步而清空
缺点:主从架构在master节点挂掉之后,slave节点虽然存活,但是无法增删改数据,只能提供查询用。如果想要基础可写入,需人工干预。
哨兵模式应运而生,哨兵可以在主发生故障后,自动进行故障转移,从从机里选出一台升级为主机,并持续监听着原来的主机,当原来的主机恢复后,会将其作为新主的从机。
redis主从搭建
我本地准备了两台服务器192.168.0.170
和 192.168.0.171
1、分别在两台服务器上执行
拉取镜像
docker pull redis
启动容器
docker run -d -p 6379:6379 --name myredis redis:latest
进入容器
docker exec -it [容器ID] /bin/bash
打开redis客户端
redis-cli
2、此时两个服务器的redis客户端还是相互独立的单应用,我将170的服务作为171的备份关联起来
在170的客户端命令中执行
slaveof 192.168.0.171 6379
完成后,在171 节点指向 info replication
看到的信息如下, 可以看出171在集群中的角色是master,并且它有一个已连接的从节点是170
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.0.170,port=6379,state=online,offset=1141,lag=1
master_replid:8954d7b8aaa855e5c465c24d2fe000501c82711a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1141
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1141
从节点170的信息如下
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.0.171
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:1707
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8954d7b8aaa855e5c465c24d2fe000501c82711a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1707
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1707
redis哨兵搭建
下载并配置一个哨兵配置文件如下,两个文件都用这个文件即可
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/sentinel.log"
dir "/tmp"
sentinel myid 14156cf20bb543add7cdce6665b4bc5e16eb82dd
sentinel monitor mymaster 192.168.0.171 6379 1
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
bind 127.0.0.1 xx.xx.xx.xx 暴露在公网时,绑定IP表示只能由这些机器访问
protected-mode no 关闭保护模式,公网时可开启
port 23679
daenibize yes 改成后台运行
pidfile /var/run/redis-sentinel.pid 进程文件
logfile /xxxxx 哨兵的日志
dir /url/local/sentinel 工作目录
sentinel monitor mymater 192.168.0.170 6379 2 核心配置:
mymaster:自定义给master命名的昵称,不能由特殊文字和空格等
ip值表示master节点所在的内网的IP
2(quorum):表示如果有两台哨兵发现了master故障,就由一个或者两个执行故障转移,重新选举master
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
mymaster 上面的master 后面是密码 sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000(毫秒) 被哨兵认为挂掉的时间段
sentinel parallel-syncs mymaster 1 选举新的master,其他slave同步数据并行的个数,为1就是1个接一个
sentinel failover-timeout mymaster 180000 准备切换的超时时间,默认3分钟
接下来,可以启动哨兵了(两台服务器都要执行)
开启哨兵容器,/root/sentinel.conf 挂载自己的数据卷
docker run --name sentinel -p 26379:26379 -v /root/sentinel.conf:/usr/local/etc/redis/sentinel.conf -d redis
随后进入容器
docker exec -it 【容器ID】 /bin/bash
启动哨兵
redis-sentinel /use/local/etc/redis/sentinel.conf
两台服务器执行完成之后,哨兵就可用的,master节点挂掉之后,slave节点会被选举为新的master节点接管工作(这个过程需要一定时间)
整合SpringBoot
修改前
spring:
redis:
database: 0
password:
host: localhost
port: 6379
修改后
spring:
redis:
database: 0
password:
sentinel:
master: mymaster
nodes: 192.168.0.170:26379,192.168.0.171:26379 # 哨兵的地址