在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
# 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. 主机用来写
,从机只用来读
。主机中的所有数据和信息都会被从机保存!
从机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服务器
该系统可以执行以下四个任务:
一般企业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
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 可以自己命名主节点名字。只能由字母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
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
sentinel failover-timeout mymaster 180000
# 不允许使用SENTINEL SET设置notification-script和client-reconfig-script。
sentinel deny-scripts-reconfig yes
# 通知脚本
# sentinel notification-script
sentinel notification-script mymaster /var/redis/notify.sh