十.Redis主从复制
1.概念
1.1 主从复制
-
是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。
-
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
1.2 主从复制的作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
1.3 使用主从复制的原因
一般来说,要将Redis运用于工程项目中,只使用一台Redis是不够的(宕机),原因如下。
- 从结构上,单个Redis服务器会发生单独故障,并且一台服务器需要处理所有的请求负载,压力较大;
- 从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量有256G,也不能将所有内存用作Redis存储内存,一般来说,单台Redis最大使用内存不应该超过20G。
2.环境配置
只需配置从库,无需配置主库(Redis默认自己本身就是主库)
127.0.0.1:6379> info replication # 查看当前库的信息
# Replication
role:master # 角色 master
connected_slaves:0 # 没有从机
master_failover_state:no-failover
master_replid:05d835578601437d0d2bf340cada2f2a4a409d2c
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个配置文件,然后修改对应的信息。
复制的文件后面加上将要开启的端口号用来区分。
[root@localhost /] cd /usr/local/bin
[root@localhost bin] ls
redis-benchmark redis-check-rdb redis-sentinel xconfig
dump.rdb redis-check-aof redis-cli redis-server
[root@localhost bin] cd xconfig/
[root@localhost xconfig] cp redis.conf redis-79.conf
[root@localhost xconfig] cp redis.conf redis-80.conf
[root@localhost xconfig] cp redis.conf redis-81.conf
1.端口(这里以redis-79.conf文件为例)
2.pid名字
3.log文件名字
4.dump.rdb文件名字
修改完毕后,启动3个redis-server,通过查看进程信息检查redis是否启动
3.开启主从复制
默认情况下,每台Redis服务器都是主节点;一般情况只用配置从机即可。
3.1 我们开启三个redis-cli 客户端,分别在6380和6381这两个客户端中执行slaveof命令。
slaveof <masterip> <masterport>
6380:
6381:
6379:
3.2 除了在客户端中使用命令开启,我们还可以在Redis的配置文件中开启。
使用这种方式开启的效果是永久的;使用命令的话,每当redis重启就会失效。
3.3 测试主从复制:
实例1:主节点写,从节点读
① 我们在主节点中set一条数据,看看从节点是否可以查看。
127.0.0.1:6379> set k1 v11
OK
127.0.0.1:6380> get k1
"v11"
127.0.0.1:6380> keys *
1) "k1"
② 从节点是可以查看的,在来看看从节点是否可以进行写操作。
127.0.0.1:6380> set k2 v2
(error) READONLY You can't write against a read only replica.
③ redis会提示不能再从节点上进行写操作。
实例2:主节点断开连接
① 我们来将主节点断开,来看看其他从节点会怎样。
② 6380这个节点还是一个从节点。(在没有配置哨兵模式的情况下,需要我们手动配置为主节点。)
③ 主节点再重写连接上,并再set一个数据,观察从节点能否获取到
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6380> get k2
"v2"
结论:主节点断开连接,从节点依旧连接到主节点上,但是这时是没有写操作的。如果主节点重新连接,从节点仍然可以获取到主节点的信息。
实例3:从节点断开连接
① 将6380从节点断开连接,之后在主节点写入一条数据
127.0.0.1:6380> shutdown
not connected>
127.0.0.1:6379> set k3 v3
OK
② 再重新启动redis的6380节点,这是如果我们获取k3是获取不到的。
127.0.0.1:6380> get k3
(nil)
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:b18099b0ac5bbf0e4575ef91e52002a9648677d6
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
③ 原因是我们是使用 slaveof 命令变成从节点的,在重启后又会默认变回主节点。
④ 但只要变回从节点,数据又可以从主节点获取了。
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6380> get k3
"v3"
4.主从复制原理
- slave 服务启动,slave 会建立和 master 的连接,发送 sync 命令。
- master 启动一个后台进程将数据库快照保存到 RDB 文件中
注意:此时如果生成 RDB 文件过程中存在写数据操作会导致 RDB 文件和当前主 redis 数据不一致,所以此时 master 主进程会开始收集写命令并将这些命令放到一个缓冲区里。
- master 就发送 RDB 文件给 slave
- slave 将文件保存到磁盘上,然后加载到内存恢复
- master 把缓冲区的命令转发给 slave
注意:后续 master 收到的写命令都会通过开始建立的连接发送给 slave
5.宕机后手动配置主节点
我们先把6381节点的主节点转换为6380,使6380即有主节点又有从节点。
根据命令展示的信息,我们可以发现它还是一个从节点,只是多了一个从节点的配置信息。
接下来我们来模拟一下主机宕机的情况,如何手动配置新的主节点。
127.0.0.1:6379> shutdown
not connected>
# 6379端口的redis以关闭
[root@localhost xconfig]# ps -ef|grep redis
root 108386 1 0 21:08 ? 00:00:10 redis-server *:6381
root 108765 95634 0 21:15 pts/3 00:00:00 redis-cli -p 6381
root 111312 1 0 22:05 ? 00:00:03 redis-server *:6380
root 111318 96156 0 22:05 pts/0 00:00:00 redis-cli -p 6380
root 112396 91314 0 22:27 pts/1 00:00:00 grep --color=auto redis
这时,我们只需使用 slaveof no one 命令断开主从复制关系,因为Redis的默认会将此节点变回master。
注意:从节点断开复制后,不会删除已有的数据,只是不再接受主节点新的数据变化。
127.0.0.1:6380> SLAVEOF no one
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=2685,lag=1
master_failover_state:no-failover
master_replid:18f9b183d38900aacfd94ce6f048cbfd724b2ea1
master_replid2:5f2d8e7929d4bf1816f118e37e341dc26f642b53
master_repl_offset:2685
second_repl_offset:2672
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1356
repl_backlog_histlen:1330
我们写入一条数据,观察6381节点能否获取。
结果是能获取到的。
6.哨兵模式
6.1 概述
主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这时需要人为干预,费时费力,还会造成一段时间内服务不可用。更多时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel(哨兵)架构来解决此问题。
能够后台监控主机是否故障,如果故障
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是 哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
这里的哨兵有两个作用:
- 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
- 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换成主机。
然而一个哨兵进程对Redis服务器进行监控,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,形成多哨兵模式。
6.2 搭建哨兵模式
① 配置文件
在Redis安装目录下有一个sentinel.conf文件,copy一份进行修改
之后我们将这个复制的文件移动到/usr/local/bin/xconfig/目录下。
这里大部分配置都是默认的,如果配置多个哨兵就修改一下端口。
#配置端口
port 26379
#以守护进程模式启动
daemonize no
#日志文件名
logfile "sentinel_26379.log"
#存放备份文件以及日志等文件的目录
dir "/tmp"
#配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,127.0.0.1代表监控的主服务器ip,6379代表端口,1代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
sentinel monitor mymaster 127.0.0.1 6379 1
#30秒ping不通主节点的信息,主观认为master宕机
sentinel down-after-milliseconds mymaster 30000
#故障转移后重新主从复制,1表示串行,>1并行
sentinel parallel-syncs mymaster 1
#故障转移开始,三分钟内没有完成,则认为转移失败
sentinel failover-timeout mymaster 180000
② 启动服务器和哨兵
[root@localhost bin]# redis-server xconfig/redis-79.conf
[root@localhost bin]# redis-sentinel xconfig/sentinel.conf
③ 观察主从关系的自动切换
我们将主节点shutdown
现在6381这个端口的Redis服务器变成master了,6380现在是它的slave。
可以从 上图sentinel 日志中出现的几个消息来进行查看:
- +switch-master :配置变更,主服务器的 IP 和地址已经改变
- +slave :一个新的从服务器已经被 Sentinel 识别并关联。
- +sdown :给定的实例现在处于主观下线状态。(减号相反)
- +odown :给定的实例现在处于客观下线状态。(减号相反)
- +convert-to-slave:切换从节点(原主节点降为从节点)
如果此时原主节点重新连接,那么只能被并入到新的主节点下,当作从服务器。
6.3 哨兵模式的优点与缺点
优点:
- 哨兵集群,基于主从复制模式,所以的主从配置优点,他都有。
- 主从可以切换,故障可以转移,系统的可用性好
缺点:
- Redis不好在线扩容,集群容量一旦到达上限,在线扩容就十分麻烦
- 实现哨兵模式的配置比较麻烦
7.复制的缺点
由于所有的写操作都是先在master上操作,然后同步更新到slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。