在Redis的持久化中曾提到,Redis高可用的方案包括持久化、主从复制(及读写分离)、哨兵和集群。其中持久化侧重解决的是Redis数据的单机备份问题(从内存到硬盘的备份);而主从复制则侧重解决数据的多机热备。此外,主从复制还可以实现负载均衡和故障恢复。
这篇文章中,将详细介绍配置基于Docker的Redis主从复制及其哨兵模式。
一、主从复制
概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,
只能由主节点到从节点
。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
作用
主从复制的作用主要包括:
-
数据冗余:
主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。 -
故障恢复:
当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。 -
负载均衡:
在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。 -
高可用基石:
除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
一般来说,要将Redis应用于工程项目中,只使用一台Redis是万万不能的,原因如下:
-
结构上 :
单个的Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载 压力较大。 -
容量上 :
单个的Redis服务器内存容量有限,就算一台Redis服务器内存容量为256G,也不能讲所有内存用作Redis存储内存。一般来说,
单台Redis最大使用内存不应该超过20G。
电商网站上的商品,一般都是一次上传,多次浏览,
读多写少
对于这种常见,我们可以使用如下这种架构:
主从复制,读写分离。80%的情况下都在进行读操作,缓解服务器压力,架构中经常使用。一主二从。
环境配置
一主两从
这里不是单机版安装部署、直接部署在3台服务器上面
我是VMare安装的Centos服务器
主机名称 | IP地址 | redis版本和角色说明 |
---|---|---|
root@node-01 | 192.168.1.110 | 6.0.6(master) |
root@node-02 | 192.168.1.111 | 6.0.6(Slave1) |
root@node-03 | 192.168.1.112 | 6.0.6(Slave2) |
此设置可以将键入命令同步到其他窗口
1. 首先、服务器上得有
redis.conf
配置文件。
我直接scp云服务器的redis配置文件
scp命令用法
$scp [[user@]host1:]file1 ... [[user@]host2:]file2 local dir
2 修改redis配置文件
# vim redis.conf
修改参数:
port 6379 # 端口
protected-mode no # 关闭保护模式
cluster-enabled no # 集群方式关闭
从机
添加参数
slaveof 192.168.1.110 6379 #配置主机信息
如果使用云服务器、这里的host可以设置为内网IP、节省宽带费用!
安装且运行
docker run -d --name my-redis -p 6379:6379 -p 16379:16379 -v /home/wei/redis/data:/data -v /home/wei/redis/config/redis.conf:/etc/redis/redis.conf --restart always --net my-redis-net redis redis-server /etc/redis/redis.conf #运行服务
报错:
WARNING: IPv4 forwarding is disabled. Networking will not work.
解决方式 :
echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf
systemctl restart network && systemctl restart docker
docker rm -f $(docker ps -aq ) #强制删除docker服务
docker run -d --name my-redis -p 6379:6379 -p 16379:16379 -v /home/wei/redis/data:/data -v /home/wei/redis/config/redis.conf:/etc/redis/redis.conf --restart always --net my-redis-net redis redis-server /etc/redis/redis.conf #运行服务
至此主从复制搭建成功
细节
1.
主机用来写
,
从机只用来读
。主机中的所有数据和信息都会被从机保存!
查看db数据
主机set数据
从机set报错
(error) READONLY You can't write against a read only replica.
2. 主机如果宕机,
从机依旧连接主机,但是没有了写操作
。主机从新启动,
从机依然可以读取主机写入的数据
如果主机断开连接了,我们可以使用slaveof no one 使自己变成主机,其他从节点手动连接到这个主机。
一般都会用到咱们Redis
哨兵模式
。
2. 从机如果宕机,
重新连接主机,从机立马从主机中同步数据过来
。
复制原理
Slave启动成功连接到master后发送一个
sync命令
;
Master接收到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,master将传送整个数据文件到slava,并完成一次完全同步。
1. 全量复制:
Slave服务接收到数据库文件数据后,将其存盘并加载到内存中。
2. 全量复制:
Master继续将新的所有收集到的修改命令依次传给slave,完成同步,但是只要重新连接master,一次完全同步(全量复制)将会被自动执行!我们的数据一定可以在从机中看到!
二、哨兵模式
主从切换技术的方法是∶
当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
1、Redis sentinel介绍
Redis Sentinel是Redis高可用的实现方案。Sentinel是一个管理多个Redis实例的工具,它可以实现对Redis的监控、通知、自动故障转移。
2、Redis Sentinel的主要功能
Sentinel的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移(failover)、主从切换。Redis的Sentinel最小配置是一主一从。 Redis的Sentinel系统可以用来管理多个Redis服务器
该系统可以执行以下四个任务:
-
监控
Sentinel会不断的检查主服务器和从服务器是否正常运行。 -
通知
当被监控的某个Redis服务器出现问题,Sentinel通过API脚本向管理员或者其他的应用程序发送通知。 -
自动故障转移
当主节点不能正常工作时,Sentinel会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点, 并且将其他的从节点指向新的主节点。 -
配置提供者
在Redis Sentinel模式下,客户端应用在初始化时连接的是Sentinel节点集合,从中获取主节点的信息。
一般企业Redis架构
这里的哨兵有三个作用:
-
通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
-
当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。
环境配置
一主两从三哨兵
主机名称 | IP地址 | redis版本和角色说明 |
---|---|---|
root@node-01 | 192.168.1.110 | 6.0.6(master) |
root@node-02 | 192.168.1.111 | 6.0.6(Slave1) |
root@node-03 | 192.168.1.112 | 6.0.6(Slave2) |
root@node-04 | 192.168.1.113 | 6.0.6(Redis Sentinel1) |
root@node-05 | 192.168.1.114 | 6.0.6(Redis Sentinel2) |
root@node-06 | 192.168.1.115 | 6.0.6(Redis Sentinel3) |
1. 配置3个哨兵,每个哨兵的配置都是一样的。在指定文件夹创建sentinel.conf文件。
protected-mode no # 关闭保护模式
sentinel monitor myredis 192.168.1.110 6379 1 # 配置监听的主服务器,
这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.1.110代表监控的主服务器,6379代表端口,1代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行
2. 启动
docker run -d --name my-redis-sentinel -p 6379:6379 -p 16379:16379 -v /home/wei/redis/data:/data -v /home/wei/redis/config/sentinel.conf:/etc/redis/sentinel.conf --restart always --net my-redis-net redis redis-sentinel /etc/redis/sentinel.conf
3. 查看 哨兵日志
docker logs my-redis-sentinel
4. 主机宕机测试
docker logs my-redis-sentinel
5. 哨兵日志监控
docker logs -f my-redis-sentinel
6. 之前的主机恢复
docker restart my-redis
由此可见,即使之前宕机的主机恢复正常。
也只能归并到当前主机下,当作从机
,这就是哨兵模式的规则
优点
1. 哨兵集群,基于主从复制模式,所有的主从配置优点,它全都有。
2. 主从可以切换,故障可以转移,系统的可用性就会更好。
3. 哨兵模式就是主从模式的升级,手动到自动,更加健壮。
优点
1. Redis不好在线扩容,集群容量一旦到达上限,在线扩容就十分麻烦!
2. 实现哨兵模式的配置其实很麻烦,里面会有很多选择!
全部配置
port 26379 # 端口
daemonize yes # 是否后台启动 docker启动必须关闭
pidfile /var/run/redis-sentinel.pid # pid文件路径
logfile "" # 日志文件路径
dir /data # 定义工作目录
# 定义Redis主的别名,IP,端口,这里的2指的是需要至少2个Sentinel认为主Redis挂了才最终会采取下一步行为
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name 可以自己命名主节点名字。只能由字母A-z,数字0-1,三个字符". - _"组成。
# quorum 配置多少个sentinel 哨兵统一认为master主节点失联,那么这是客观上就认为主节点失联了。
sentinel monitor mymaster 192.168.1.110 6379 2
# 如果mymaster 30秒内没有响应,则认为其主观失效
sentinel down-after-milliseconds mymaster 30000
# 当在Redis实例配置文件中开启了requierpass foobred密码授权,所有客户端连接都需要提供密码。
# 设置哨兵sentinel连接主从的密码必须为主从设置一样验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456
# 如果master重新选出来后,其它slave节点能同时并行从新master同步数据的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保守的设置为1,同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。
# 这个数字越小,完成failover所需时间越长。
# 如果数字越大,就意味着多个slave因为replication而不可用。
# 通常将这个值设置为1 来保证每次只有一个slave处于不能处理命令请求的状态。
sentinel parallel-syncs mymaster 1
# 故障转移的超时时间failover-timeout,默认三分钟,可以用在以下这些方面:
## 1. 同一个sentinel对同一个master两次failover之间的间隔时间。
## 2. 当一个slave从一个错误的master那里同步数据时开始,直到slave被纠正为从正确的master那里同步数据时结束。
## 3. 当想要取消一个正在进行的failover时所需要的时间。
## 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来同步数据了
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
# 不允许使用SENTINEL SET设置notification-script和client-reconfig-script。
sentinel deny-scripts-reconfig yes
# 通知脚本
# sentinel notification-script <master-name> <script-path>
sentinel notification-script mymaster /var/redis/notify.sh