Redis 主从+哨兵
一、Redis 主从复制
搭建环境: + +
1 准备Redis目录
# 创建redis工作目录
mkdir -p /data/redis
cd /data/redis
# 创建redis存数据目录
mkdir master_data salve01_data salve02_data
# 创建redis主从节点配置文件
touch redis_master.conf redis_salve01.conf redis_salve02.conf
2 准备配置文件
2.1 redis_master.conf
# 后台运行
daemonize yes
# 注释本机访问限制
# bind 127.0.0.1
# 关闭保护模式
propected_mode no
# RDB文件地址
dir /data/redis/master_data/
# RDB文件名称
dbfilename dump6379.rdb
# pid文件
pidfile /var/run/redis_6379.pid
# 日志级别
loglevel notice
# 日志文件
logfile /data/redis/master_data/master.log
# 密码
requirepass 111111
# 指定端口
port 6379
# 配置访问主节点的密码
# 这里配置是为了加了哨兵节点后,主节点宕机重启时,连接新的主节点的密码
masterauth 111111
2.2 redis_salve01.conf
propected_mode yes
daemonize no
# RDB文件地址
dir /data/redis/salve01_data/
# RDB文件名称
dbfilename dump6380.rdb
# pid文件
pidfile /var/run/redis_6380.pid
# 日志级别
loglevel notice
# 日志文件
logfile /data/redis/salve01_data/salve01.log
# 密码
requirepass 111111
# 注释本机访问限制
# bind 127.0.0.1
# 从节点端口
port 6380
# 主节点地址和端口
# 由于这里是采用的docker,docker自定义网络采用容器名称
replicaof 192.168.163.126 6379
# 配置访问主节点的密码
masterauth 111111
2.3 redis_salve02.conf
propected_mode yes
daemonize no
# RDB文件地址
dir /data/redis/salve02_data/
# RDB文件名称
dbfilename dump.rdb
# pid文件
pidfile /var/run/redis_6381.pid
# 日志级别
loglevel notice
# 日志文件
logfile /data/redis/salve02_data/salve02.log
# 密码
requirepass 111111
# 注释本机访问限制
# bind 127.0.0.1
# 从节点端口
port 6381
# 主节点地址和端口
# 由于这里是采用的docker,docker自定义网络采用容器名称
replicaof 192.168.163.126 6379
# 配置访问主节点的密码
masterauth 111111
3 启动节点
# 先启动master节点
redis-server /data/redis/redis_master.conf
redis-server /data/redis/redis_salve01.conf
redis-server /data/redis/redis_salve02.conf
4 查看状态
redis-cli -p 6379 -a 111111
info replication
## Replication
#role:master
#connected_slaves:2
# 重新开一个连接
redis-cli -p 6380 -a 111111
info replication
# Replication
#role:slave
#master_host:192.168.163.126
#master_port:6379
#master_link_status:up
# 再开一个连接
redis-cli -p 6381 -a 111111
info replication
# Replication
#role:slave
#master_host:192.168.163.126
#master_port:6379
#master_link_status:up
5 补充
除了通过配置文件方式实现主从同步,还可以通过命令行方式实现(重启后失效)
# 进入从机redis客户端 执行以下命令 SALVEOF 192.168.163.126:6379
从机也可以将主节点设置为另一个从机(这样就是6379--->6380--->6381)
6 总结
- slave启动,同步初请
- slave启动成功连接到master后会发送一个sync命令
- 首次连接,全量复制
- master节点收到sync命令后会开始在后台保存快照(即RDB持久化,主从复制时会触发RDB),同时收集所有接收到的用于修改数据集命令缓存起来,master节点执行RDB持久化完后,master将rdb快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步
- 而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化
- 心跳持续,保持通信
- 进入平稳,增量复制
- 从机下线,重连续传
- master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId, offset是保存在backlog中的。
7 主从复制的缺点
复制延时,信号衰减
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
master宕机了如何办
master节点宕机了,从节点并不会自动转为master,需要进行人工干预(就需要引入哨兵模式)
二、Redis 哨兵
1 哨兵的作用:
- 监控redis运行状态,括master和slave
- 当master down机,能自动将slave切换成新master
- 哨兵节点不存放数据,只当作吹哨人
2 sentinel.conf 配置项
参数 | 说明 |
---|---|
设置要监控的master服务器。quorum表示最少有几个哨兵认可客观下线,同意故障迁移的法定票数。 | |
master设置了密码,连接master服务的密码 | |
sentinel down-after-milliseconds <master-name> <milliseconds> | 指定多少毫秒之后,主节点没有应答哨兵,此时哨兵主观上认为主节点下线 |
sentinel parallel-syncs <master-name><nums> | 表示允许并行同步的slave个数,当Master挂了后,哨兵会选出新的Master,此时,剩余的slave会向新的master发起同步数据 |
sentinel failover-timeout <master-name> <milliseconds> | 故障转移的超时时间,进行故障转移时,如果超过设置的毫秒,表示故障转移失败 |
sentinel notification-script<master-name> <script-path> | 配置当某一事件发生时所需要执行的脚本 |
sentinel client-reconfig-script <master-name> <script-path> | 客户端重新配置主节点参数脚本 |
我们知道,网络是不可靠的,有时候一个sentinel会因为网络堵塞而误以为一个master redis已经死掉了,在sentinel集群环境下需要多个sentinel互相沟通来确认某个master是否真的死了,quorum这个参数是进行客观下线的一个依据,意思是至少有quorum个sentinel认为这个master有故障,才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以,这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。
3 启动3个哨兵节点
3.1 准备配置文件
mkdir -p /data/redis/sentinel
cd /data/redis/sentinel
touch sentinel26379.conf sentinel26380.conf sentinel26381.conf
三个配置文件除了端口和配置文件有区别,其他内容一模一样
bind 0.0.0.0
daemonize yes
protected-mode no
port 26379
#port 26380
#port 26381
logfile "/data/redis/sentinel/sentinel26379.1og"
#logfile "/data/redis/sentinel/sentinel26380.1og"
#logfile "/data/redis/sentinel/sentinel26381.1og"
pidfile /var/run/redis-sentinel26379.pid
#pidfile /var/run/redis-sentinel26380.pid
#pidfile /var/run/redis-sentinel26381.pid
dir /data/redis/sentinel
# 监控的redis主节点 最后一个2代表有2票以上则该master有问题
sentinel monitor mymaster 192.168.163.126 6379 2
# 连接主节点的密码
sentinel auth-pass mymaster 111111
3.2 启动
redis-sentinel /data/redis/sentinel/sentinel26379.conf
redis-sentinel /data/redis/sentinel/sentinel26380.conf
redis-sentinel /data/redis/sentinel/sentinel26381.conf
4 SHUTDOWN掉主节点
ps -ef|grep redis-server |grep 6379
kill pid
# 重启主节点
redis-server /data/redis/redis_master.conf
# 再次查看主节点状态
redis-cli -p 6379 -a 111111
# Replication
#role:slave
#master_host:192.168.163.126
#master_port:6380
#master_link_status:up
# 主节点已经变成了6380端口的节点
5 哨兵运行原理
当一个主从配置中的master失效之后,sentinel可以选举出一个新的master用于自动接替原master的工作,主从配置中的其他redis服务器自动指向新的master同步数据
一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换
所谓主观下线(Subiectively Down,简称 SDOWN)指的是单个Sentinel实例对服务器做出的下线判断,即单个sentnel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。主观下线就是说如果服务器在[sentinel down-ater-miiseconds]给定的亳秒数之内没有回应PING命令或者返回一个错误消息, 那么这个Sentinel会主观的(单方面的)认为这个master不可以用了
意思是至少有quorum个sentinel认为这个master有故障才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。
当主节点被判断客观下线以后,各个哨兵节点会进行协商先选举出一个领导者哨兵节点,并由该领导者节点也即进行故障迁移。
Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者- (redis.conf的priority配置,值越小优先级越高)
- (复制的偏移量)
6 哨兵使用建议
- 哨兵节点的数量应为多个,哨兵本身应该集群,保证高可用
- 哨兵节点的数量应该是奇数
- 各个哨兵节点的配置应一致
- 如果哨兵节点部署在Docker等容器里面,尤其要注意端口的正确映射
- 哨兵集群+主从复制,并不能保证数据零丢失
三、Docker方式启动主从+哨兵
1 准备配置文件
mkdir /data/docker/redis/compose
touch master.conf salve.conf sentinel.conf
2 准备compose.yaml
version : "3"
services:
redis-master:
image: redis:7.0.13
container_name: redis-master
ports:
- "6380:6379"
networks:
redis-net:
ipv4_address: 172.30.0.2
volumes:
- /data/docker/redis/compose/master.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
redis-salve01:
image: redis:7.0.13
container_name: redis-salve01
ports:
- "6381:6379"
networks:
redis-net:
ipv4_address: 172.30.0.3
volumes:
- /data/docker/redis/compose/salve.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
depends_on:
- redis-master
redis-salve02:
image: redis:7.0.13
container_name: redis-salve02
ports:
- "6382:6379"
networks:
redis-net:
ipv4_address: 172.30.0.4
volumes:
- /data/docker/redis/compose/salve.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
depends_on:
- redis-master
redis-sentinel01:
image: redis:7.0.13
container_name: redis-sentinel01
networks:
redis-net:
ipv4_address: 172.30.0.5
volumes:
- /data/docker/redis/compose/sentinel.conf:/etc/redis/sentinel.conf
command: redis-sentinel /etc/redis/sentinel.conf
depends_on:
- redis-master
- redis-salve01
- redis-salve02
redis-sentinel02:
image: redis:7.0.13
container_name: redis-sentinel02
networks:
redis-net:
ipv4_address: 172.30.0.6
volumes:
- /data/docker/redis/compose/sentinel.conf:/etc/redis/sentinel.conf
command: redis-sentinel /etc/redis/sentinel.conf
depends_on:
- redis-master
- redis-salve01
- redis-salve02
redis-sentinel03:
image: redis:7.0.13
container_name: redis-sentinel03
networks:
redis-net:
ipv4_address: 172.30.0.7
volumes:
- /data/docker/redis/compose/sentinel.conf:/etc/redis/sentinel.conf
command: redis-sentinel /etc/redis/sentinel.conf
depends_on:
- redis-master
- redis-salve01
- redis-salve02
networks:
redis-net:
driver: bridge
ipam:
config:
- subnet: 172.30.0.0/16
gateway: 172.30.0.1
3 修改master.conf
# 密码
requirepass 111111
# 注释本机访问限制
# bind 127.0.0.1
# 配置访问主节点的密码
# 这里配置是为了加了哨兵节点后,主节点宕机重启时,连接新的主节点的密码
masterauth 111111
4 修改salve.conf
# 密码
requirepass 111111
# 注释本机访问限制
# bind 127.0.0.1
# 主节点地址和端口
replicaof 172.21.0.2 6379
# 配置访问主节点的密码
masterauth 111111
5 修改sentinel.conf
# 复制以下内容到3个配置文件
bind 0.0.0.0
# 配置主节点地址
sentinel monitor mymaster 172.21.0.2 6379 2
# 配置主节点的密码
sentinel auth-pass mymaster 111111
6 启动主从+哨兵节点
docker-compose up -d

7 进入主节点容器查看状态
# 进入主节点容器
docker exec -it redis-master bash
# 启动redis客户端
redis-cli -a 111111
# 查看主从状态
info replication
set k1 v1
#停止主节点
SHUTDOWN
#此时可以进入其他从节点,查看状态。等一会会有一个从节点晋升为主节点。
#当主节点重启时,会加入新的主节点
