Redis之主从复制

前言

  Redis拥有非常强大的主从复制功能,而且还支持一个master可以拥有多个slave,而一个slave又可以拥有多个slave,从而形成强大的多级服务器集群架构。

  我们前面介绍的都是在一台服务器上进行的,也就是说读和写以及备份操作都是在一台Redis服务器上进行的,那么随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都很快,但是一定程度上也会造成一定的延时。

  为了解决访问量大的问题,通常会采取的一种方式是主从架构Master/Slave,Master 以写为主,Slave 以读为主,Master 主节点更新后根据配置,自动同步到从机Slave 节点。

  

 主从复制模式

配置并安装启动服务

  1). master_6379 主服务器 不做更改

  2). 配置从机的redis.windows.conf文件

从机地址:bind 127.0.0.1(代表本地,如果是其他机器,则是对应的IP地址)

配置端口号port 6380

主机地址slaveof 127.0.0.1 6379 

日志文件名字logfile "6380.log"

RDB和AOF文件名dbfilename dump_6380.rdb       appendfilename "appendonly.aof"

如上,基本的配置就完成了,有几个从机对应端口号进行配置。

  3)进行服务安装

  我们只是配置redis从机服务器,并没有安装在PC上。当然直接可在安装文件夹中点击redis-server.exe和redis-cli.exe进行启动,但是当窗口关闭后,redis也就关闭。我们做的是让redis“永久”开启。

1.配置文件

 配置介绍略。以6380为例

port 6380

2.安装服务

  redis-server --service-install --service-name redis_6380 redis.windows-service-6380.conf

3.启动服务

  redis-server --service-start --service-name redis_6380

4.停止服务

  redis-server --service-stop --service-name redis_6380

5.卸载服务

  redis-server --service-uninstall --service-name redis_6380

我们主要用到的是安装启动服务命令,其他从机redis同理。

设置主从关系

注意:

  有多个redis服务器文件夹时,启动所有的redis服务器后,要通过命令指定端口号 打开redis-cli客户端。

  不能在文件夹中直接点redis-cli.exe打开,不管你在哪个redis服务文件夹下 都是打开6379这个端口服务客户端。

  找到对应各个redis文件下,在窗口中输入:redis-cli -p  6380 [ redis-cli -p 端口号]

(1)通过 info replication 命令查看节点角色

 

  发现三个节点都是扮演的Master角色。那么如何将6380和6381节点变为slave角色呢?

(2)选择6380端口和6381端口,执行命令:slaveof 127.0.0.1 6379

我们再看6379节点信息

这里通过命令来设置主从关系,一旦服务重启,那么角色关系将不复存在。想要永久的保存这种关系,可以通过配置redis.conf 文件来

(3)测试主从关系

 ① 增量赋值

 主节点执行 set k1 v1 命令,从节点 get k1 能获取吗?

 

 由图可知可以获取

②、全量复制

  通过执行 SLAVEOF 127.0.0.1 6379,如果主节点 6379 以前还存在一些 key,那么执行命令之后,从节点会将以前的信息也都复制过来吗?

  答案也是肯定的,这里我就不贴测试结果了。

③、主从读写分离

 主节点能够执行写命令,从节点能够执行写命令吗?

这里的原因是在配置文件 6381 redis.conf 中对于 slave-read-only 的配置

 

 如果我们将其修改为 no 之后,执行写命令是可以的。

④、主节点宕机

 主节点 Maste 挂掉,两个从节点角色会发生变化吗?

 

 

 上图可知主节点 Master 挂掉之后,从节点角色还是不会改变的。

 ⑤、主节点宕机后恢复

 主节点Master挂掉之后,马上启动主机Maste,主节点扮演的角色还是 Master 吗?

 

 就是说主节点挂掉之后重启,又恢复了主节点的角色。

小总结

1. 主机添加修改操作,从机是可见的;

2. 设置从机节点后,从节点会将主机以前的信息都复制过来

3. 主机节点可读可写,从机节点只可读。可在配置文件设置。

4. 主机挂掉后,从机角色不会变。

5. 主节点宕机后重启,会恢复主节点角色

哨兵模式

   通过前面的配置,主节点Master只有一个,一旦主节点挂掉之后,从节点没发担起主节点的任务,那么整个系统也无法运行。如果主节点挂掉之后,从节点能够自动变成主节点,那么问题就解决了,于是哨兵模式诞生了。

  哨兵模式就是不时地监控redis是否按照预期良好地运行(至少是保证主节点是存在的),若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系。

哨兵模式搭建步骤

1. 主从配置,设置配置文件

  参考上方,设置1主机,2从机

2. 哨兵配置

  每个redis目录中创建一个sentinel.conf文件

 2.1  master_6379的sentinel.conf文件配置如下

#当前Sentinel服务运行的端口
port 26379
#master
#Sentinel去监视一个名为mymaster的主redis实例,这个主实例的IP地址为本机地址127.0.0.1,端口号为6379,
#而将这个主实例判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行
#sentinel monitor 被监控机器的名字(自己起名字) ip地址 端口号 得票数。下面的得票数为1表示表示主机挂掉后salve投票看让谁接替成为主机,得票数大于1便成为主机 sentinel monitor redis6379
127.0.0.1 6379 1 #指定了Sentinel认为Redis实例已经失效所需的毫秒数。当 实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。 #只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行 sentinel down-after-milliseconds redis6379 5000 #指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长 sentinel config-epoch redis6379 12 #如果在该时间(ms)内未能完成failover操作,则认为该failover失败 sentinel leader-epoch redis6379 13

 2.2 slave_6380中的sentinel.conf文件配置

#当前Sentine2服务运行的端口
port 26479
#slave1
sentinel monitor redis6379 127.0.0.1 6379 1
sentinel down-after-milliseconds redis6379 5000
sentinel config-epoch redis6379 12
sentinel leader-epoch redis6379 13

  2.3 slave_6381中的sentinel.conf文件配置

#当前Sentine3服务运行的端口
port 26579
#slave2
sentinel monitor redis6379 127.0.0.1 6379 1
sentinel down-after-milliseconds redis6379 5000
sentinel config-epoch redis6379 12
sentinel leader-epoch redis6379 13

 

3. 启动服务

  3.1 将所有redis服务器启动,设置主从关系。

  3.2 启动所有的redis哨兵服务器

在主节点文件夹下,通过cmd窗口,输入如下命令:

  redis-cli -p 26379

其他从节点的哨兵启动同理。

主从服务

 哨兵服务器

 

4. 测试服务

1) 查看redis服务状态,命令: info replication

 

 2)查看sentinel的状态,命令: info sentinel

 

3) redis主从自动failover测试

    停止master服务器,查看剩余服务器的状态

 

  从上图中可以看出来,master的服务器端口从6379变成了6380,也就是说redis自动的实现了主从切换,

 我们可以在查看下sentinel的状态,如下: 

 

我们发现sentinel监控到127.0.0.1:6379已经无法ping通了,切换master服务器为127.0.0.1:6380 

ps:哨兵模式也存在单点故障问题,如果哨兵机器挂了,那么就无法进行监控了,解决办法是哨兵也建立集群,Redis哨兵模式也支持集群分布。

主从复制原理

Redis的复制功能分为同步(sync)和命令传播(command propagate)两个操作。

① 旧版同步

  当从节点发出slaveof命令,要求从服务器复制主服务器时,从服务器通过向主服务器发送sync命令来完成。该命令执行步骤:

1. 从服务器向主服务器发送sync命令

2. 收到sync命令的主服务器执行bgsave命令,在后台生成一个rdb文件,并使用一个缓冲区记录从开始执行的所有写命令

3. 当主服务器的bgsave命令执行完毕时,主服务器会将bgsave命令生成的rdb文件发送给从服务器,从服务器接收此rdb文件,并将服务器状态更新为rdb文件记录的状态。

4. 主服务器将缓冲区的所有写命令也发送给从服务器,从服务器执行相应命令。

② 命令传播

  当同步操作完成之后,主服务器会进行相应的修改命令,这时候从服务器和主服务器状态就会不一致。

  为了让主服务器和从服务器保持状态一致,主服务器需要对从服务器执行命令传播操作,主服务器会将自己写命令发送给从服务器执行。从服务器执行相应的命令之后,主从服务器状态继续保持一致。

  总结: 通过同步操作以及命令传播功能,能够很好的保证了主从一致的特性。

  但是我们考虑一个问题,如果从服务器在同步主服务器期间,突然断开了连接,而这时候主服务器进行了一些写操作,这时候从服务器恢复连接,如果我们在进行同步,那么就必须将主服务器从新生成一个RDB文件,然后给从服务器加载,这样虽然能够保证一致性,但是其实断开连接之前主从服务器状态是保持一致的,不一致的是从服务器断开连接,而主服务器执行了一些写命令,那么从服务器恢复连接后能不能只要断开连接的哪些写命令,而不是整个RDB快照呢?

  同步操作其实是一个非常耗时的操作,主服务器需要先通过 BGSAVE 命令来生成一个 RDB 文件,然后需要将该文件发送给从服务器,从服务器接收该文件之后,接着加载该文件,并且加载期间从服务器无法处理其他命令的。

  为了解决这个问题,Redis从2.8版本之后,使用了新的同步命令 PSYNC 来代替 SYNC 命令。该命令的部分重同步功能用于处理断线后重复制的效率问题。也就是说当从服务器在断线后重新连接主服务器时,主服务器只将断开连接后执行的写命令发送给从服务器,从服务器只需要接收并执行这些写命令即可保持主从一致。

主从复制的缺点

  主从复制虽然解决了主节点的单点故障问题,但是由于所有的写操作都是在 Master 节点上操作,然后同步到 Slave 节点,那么同步就会有一定的延时,当系统很繁忙的时候,延时问题就会更加严重,而且会随着从节点slave的增多而愈加严重。

 

 参考:https://blog.csdn.net/weixin_41846320/article/details/83753182

posted @ 2020-01-17 23:05  王大军  阅读(177)  评论(0)    收藏  举报