概念
- 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能有主节点到从节点。master以写为主,slave以读为主。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。 - 主从复制的作用:
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载;尤其是在写少读多的场景下,通过多个节点分担读负载,可以大大提高Redis服务器的并发量
- 高可用基石:主从复制还是哨兵和集群能够实施的基础。
- 一般来说,要将Redis运用于工程项目中,只是用一台Redis是万万不能的(宕机),原因如下:
- 从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大。
- 从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量为256G,也不能将所有内存用作Redis存储内存,一般来说,单台Redis最大使用内存不应该超过20G。
环境配置
只配置从库,不用配置主库
127.0.0.1:6379> info replication # 查看当前库的信息
# Replication
role:master # 角色 master
connected_slaves:0 # 没有从机
master_replid:1255730493c4670e65b496785dfe90271e60c645
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
复制3个配置文件,然后修改对应信息
- 端口
- pid名字
- log文件名字
- dump.rdb名字
修改完毕后,启动三个redis服务器,可以通过进程查看
一主二从
默认情况下,每台Redis服务器都是主节点;一般情况下只用配置从机就好了
一主(79)二从(80、81)
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 # 找一个主机
OK
127.0.0.1:6380> info replication
# Replication
role:slave # 当前角色是从机
master_host:127.0.0.1 # 可以看到主机的信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:775f0d2e16219eadd1fe36df246f55242604a4b9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
# 在主机中查看
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1 # 多了从机的配置
slave0:ip=127.0.0.1,port=6380,state=online,offset=224,lag=1
master_replid:775f0d2e16219eadd1fe36df246f55242604a4b9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:224
如果两个都配置完了,就是有两个从机的
真实的从主配置应该在配置文件中配置,这样的话是永久的,我们这里使用的命令是暂时的。
config主从配置
测试
主机可以写,从机不能写只能读!主机中的所有信息和数据,都会自动被从机保存!
-
主机写:
-
从机读取:
- 主机断开连接,从机依旧可以连接到主机,但是没有写操作,这个时候,主机如果回来,从机依旧可以直接获取到主机写的信息。
- 如果使用命令行来配置主从,这个时候如果重启了,就会变回从机!只要变为从机,立马就会从主机中获取值!
复制原理
- slave 启动成功连接到 master 后会发送一个sync同步命令
- master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,master将传送整个数据文件到slave,并完成一次完全同步。
- 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
- 增量复制:master继续将新的所有收集到的修改命令依次传个slave,完成同步
- 但是只要重新连接master,一次完全同步(全量复制)将被自动执行!我们的数据一定可以在从机中看到!
哨兵模式
概述
监控master和slave的运行状态,若master宕机了会根据投票数自动将slave转换为master。哨兵模式是一个独立的进程,会独立运行,其原理是哨兵通过发送命令,等待Redis服务器的响应,从而监控运行的多个Redis实例
这里的哨兵(Sentinel)有两个作用:
- 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
- 当哨兵监测到master主机宕机,会自动将slave切换为master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机。
然而一个哨兵进程对Redis服务器的监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控,各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover[故障转移]过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象称为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由任一哨兵发起,进行failover操作。切换成功后通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。
测试
目前状态是一主二从!
- 配置哨兵配置文件 sentinel.conf
# sentinel monitor <master-group-name> <ip> <port> <quorum>
# quorum:是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效。
sentinel monitor myredis 127.0.0.1 6379 1
- 启动哨兵
[root@localhost bin]# redis-sentinel dconfig/sentinel.conf
111923:X 04 Mar 2021 16:44:03.479 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
111923:X 04 Mar 2021 16:44:03.479 # Redis version=5.0.9, bits=64, commit=00000000, modified=0, pid=111923, just started
111923:X 04 Mar 2021 16:44:03.479 # Configuration loaded
111923:X 04 Mar 2021 16:44:03.480 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 111923
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
111923:X 04 Mar 2021 16:44:03.480 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
111923:X 04 Mar 2021 16:44:03.484 # Sentinel ID is 18a03ac10bc8514823834e0861b1840a44c9a980
111923:X 04 Mar 2021 16:44:03.484 # +monitor master myredis 127.0.0.1 6379 quorum 1
111923:X 04 Mar 2021 16:44:03.485 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
111923:X 04 Mar 2021 16:44:03.485 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
如果master 节点断开了,这个时候就会从slave中随机选择一个服务器!(这里面有一个投票算法)
哨兵日志
如果主机此时回来了,只能归并到新的主机下,当做从机,这就是哨兵模式的规则!
哨兵模式的优缺点
优点:
- 哨兵集群,基于主从复制模式,所有的主从配置优点,它全有。
- 主从可以切换,故障可以转移,系统的可用性就会更好。
- 哨兵模式就是主从模式的升级,手动到自动,更加健壮。
缺点:
- Redis 不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦。
- 实现哨兵模式的配置其实是很麻烦的,里面有很多配置。
# Example sentinel.conf
# 哨兵sentinel实例运行的端口 默认26379【如果有哨兵集群,我们还需要配置每个哨兵的端口】
port 26379
# 哨兵sentinel的工作目录
# dir <working-directory>
dir /tmp
# 哨兵sentinel监控的redis主节点的 ip port
# master-name 可以任意命名,只能由字母A-z、数字0-9、这三个字符 ".-_"组成
# quorum 是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效。
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
# 如果redis配置了密码,那这里必须配置认证,否则不能自动切换
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123password
#主节点或副本在指定时间内没有回复PING,便认为该节点为主观下线 S_DOWN 状态。【默认30s】
sentinel down-after-milliseconds mymaster 30000
# 指定在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步
# numslaves:这个数字越小,完成failover所需的时间越长;但是这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
# 故障转移的超时 failover-timeout 可以用在以下这些方面:
# 1. 同一个sentinel 对同一个master两次failover之间的间隔时间。
# 2. 当一个slave从一个错误的master哪里同步数据开始计算时间,直到slave被纠正为向正确的master那里同步数据时。
# 3. 取消已在进行但未生成任何配置更改的故障转移所需的时间
# 4. 当进行failover时,配置所有slaves指向新的master所需的最大时间。即使过了这个超时,slaves依然会被正确配置为指向master。
# 默认3分钟
sentinel failover-timeout mymaster 180000
# 脚本执行
# sentinel notification-script和sentinel reconfig-script用于配置调用的脚本,以通知系统管理员或在故障转移后重新配置客户端。
# 脚本使用以下规则执行以进行错误处理:
# 如果脚本以“1”退出,则稍后重试执行(最多重试次数为当前设置的10次)。
# 如果脚本以“2”(或更高的值)退出,则不会重试执行。
# 如果脚本因为收到信号而终止,则行为与退出代码1相同。
# 脚本的最长运行时间为60秒。 达到此限制后,脚本将以SIGKILL终止,并重试执行。
# 通知脚本
# sentinel notification-script <master-name> <script-path>
# 为警告级别生成的任何Sentinel事件调用指定的通知脚本(例如-sdown,-odown等)。
# 此脚本应通过电子邮件,SMS或任何其他消息传递系统通知系统管理员 监控的Redis系统出了问题。
# 使用两个参数调用脚本:第一个是事件类型,第二个是事件描述。
# 该脚本必须存在且可执行,以便在提供此选项时启动sentinel。
sentinel notification-script mymaster /var/redis/notify.sh
# 客户重新配置脚本
# sentinel client-reconfig-script <master-name> <script-path>
# 当主服务器因故障转移而变更时,可以调用脚本执行特定于应用程序的任务,以通知客户端,配置已更改且主服务器地址已经变更。
# 以下参数将传递给脚本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# <state> 目前始终是故障转移 "failover"
# <role> 是 "leader" 或 "observer"
# 参数 from-ip, from-port, to-ip, to-port 用于传递主服务器的旧地址和所选副本的新地址。
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh