Redis5.0.4复制

redis的复制很简单,由于资源限制,本例中采用两台虚拟机,每台虚拟机安装两个redis实例,共四个来测试

一、安装redis

https://www.cnblogs.com/qq931399960/p/10616459.html

二、当前安装的redis分别为

192.168.102.69:6379 (master)

192.168.102.69:6380 (slave) 

192.168.102.52:6379 (slave)

192.168.102.52:6379 (slave)

三、配置主从复制

5.0版本使用REPLICAOF代替了之前版本的SLAVEOF,如果使用5.0及之后版本,则建议新命令REPLICAOF。

1、命令行方式

分别登录各slave redis命令行,执行auth xxx赋权,执行如下命令(重启之后无效)

REPLICAOF 192.168.102.69 6379
CONFIG SET masterauth 12345

若取消复制,则执行如下命令即可

REPLICAOF no one

2、配置方式(永久生效,本例中使用配置方式)

redis slave配置文件中添加如下配置,重启redis

replicaof 192.168.102.69 6379
masterauth 12345

若取消复制,只需要去掉上述配置,重启即可

四、验证

1、登录从实例,查看info

2、登录主实例,查看info

重启之后,replication id和offset会被重置

主实例添加key,从实例查询,已同步,ok

五、配置只有N个连接复制的时候才允许主实例写操作

个人觉得,若使redis节点高可用,则该项应该使用默认配置,否则可能会出现几个节点不可用,造成写操作失败。

该功能工作原理如下:

1、从实例每秒ping主实例,确认已处理的复制流的数量

2、redis主实例记住最后接收到的从实例ping的时间

3、用户配置从实例的最小数量在小于指定的最大延迟(秒)时间时可写。

该功能有两个配置控制(5.0版本之前replicas改为slaves)

min-replicas-to-write <number of slaves>  (默认0)
min-replicas-max-lag <number of seconds>  (默认10)

在redis master配置文件中添加配置

min-replicas-to-write 4
min-replicas-max-lag 10

意为,当至少4个slave连接master的延迟时间小于10秒时,主实例才可以进行写操作。

也可以通过命令行在重启之前生效

127.0.0.1:6379> CONFIG SET min-replicas-to-write 4
OK
127.0.0.1:6379> CONFIG GET min-replicas-to-write
1) "min-replicas-to-write"
2) "4"
127.0.0.1:6379> 

登录master,执行测试

 

如下为在redis官网获取到的一些信息

从实例在与主实例的连接断开后,会自动重连,并且尝试作为主实例的一个精确副本。其工作机制如下

1、当主从实例正常连接时,主实例发送命令流给从实例来保证数据的一致性

2、由于网络问题或者检测到超时等引起的主从连接断开,从实例将重新连接主实例并尝试进行部分再同步,也就是说,从实例将获取在连接断开期间丢失的命令流。

3、当部分再同步不可实现,从实例将会请求一个全量再同步。其中包括主实例创建一个所有数据的快照,并且发送给从实例,然后继续发送数据集改变时的命令流。

默认情况下,redis使用高性能,低延迟的异步复制。redis从实例异步的获取接收到的主实例数据量,因此主实例不用每次都等待从实例处理命令,但是主实例嫩巩固知道从实例的命令的执行状态

redis基本复制规则

1、redis使用异步复制,异步进行从实例到主实例的数据处理量的确认

2、主实例可以有多个从实例

3、从实例可以从其他从实例处接受数据,从redis4.0起,所有子从实例都从主实例获取精确的复制流

4、在主实例侧,redis复制是非阻塞的。当一个或者多个从实例执行初始化同步或者部分再同步时,主实例将继续处理查询请求。

5、在从实例侧,复制也基本上是非阻塞的。当从实例正在执行初始化同步时,它可以使用老版本的数据集处理查询。另外,可以在从实例中配置当复制流停止后,返回一个错误给客户端。但是在数据初始化同步之后,需要删除旧数据,加载新数据,在这一时期,从实例将会阻塞所有接收到的连接(对于一个非常大数据集,可能会持续几秒)。自从redis4.0,可以配置在另外一个线程中删除旧数据,但是仍然在主线程中加载新的初始化数据,并且阻塞从实例。

6、redis复制可以应用于可扩展性,比如有多个从实例提只读服务,或者仅仅只是用于数据安全和高可用

7、可以使用复制来避免主实例将全部数据集写入到磁盘中。这种使用方式一般在主实例中禁止了持久化,但必须谨慎的设置该功能,因为主实例启动后,将会清空所有数据,如果从实例向主实例获取数据,那么从实例的数据也将为空

强烈建议在主从实例中都打开持久化。

每个redis主实例都有一个relication id,它由一个大的伪随机字符串组成,标记数据集的给定描述。每个主实例还具有一个偏移量(offset),这个偏移量会一直增加,即使没有从节点连接,复制偏移量也会增加,重启之前replication id不会变化,重启之后,replication id和offset都会发生变化。一般replciation id和offset来确定主实例的一个准确的版本。

当从实例连接到主实例,从实例通过PSYNC命令来发送他们的最新的旧主实例replication id和offset,使用这种方式,主服务器可以只发送所需的增量部分命令流。但是如果主实例缓冲区没有足够的backlog,或者从实例指向了一个位置的历史replication id,那么将会发生全量再同步。

全量再同步工作原理

主实例启动一个后台保存进程生成RDB文件,如此同时,开始缓存所有从客户端获取的写命令,当后台保存进程结束,主实例将这个RDB数据库文件传送给从实例,从实例将其保存在磁盘,并且加载到内存,之后主实例发送所有缓存的命令给从实例。

SYNC是一个旧的命令,不支持部分再同步,在新版本中已经使用PSYNC代替,考虑到向后兼容,SYNC命令没有去除

主从连接断开后,从节点可以自动重新连接主实例。若果主实例接收到多个并发的同步请求,其将只执行一个后台保存进程生成RDB文件,然后将该RDB文件发送给以上并发同步的各请求

 Replication id的解释

如果两个实例具有相同的replication id和offset,那么他们具有相同的数据集。每次主实例重启或者从实例提升为主实例,对于这个实例来讲,将会产生新的replication id,连接到主实例的从实例将在握手之后继承其replication id。因此具有相同id 的两个实例是有关联的,因为他们可能在不同的

时间点获取到了相同的数据。对于一个保存有最新数据的给定历史节点,偏移量作为一个逻辑时间来理解。例如:A和B具有相同的replication id,但是其中一个的偏移量为1000,另外一个偏移量为1023,这意味着第一个实例少执行了一些命令,也可以说,A实例,执行一些命令之后可以达到B实例的状态。

redis具有两个replication id的原因在于,提升为主实例的从实例。在故障转移中,被提升为主实例的从实例仍然需要记住它过去的replication id,因为这个replication id是之前主实例的一个id之一,在这种情况下,其他将与新主实例进行同步的从实例使用之前旧的主实例的replciation id与新的主实例之间可以执行部分同步。这和预期一致,因为当从实例提升为主实例,它将辅id设置为主id,在id转换时,记录偏移量,之后选出一个新的随机replication id,因为一个新的历史记录开始。档处理新从实例连接,主实例将用当前的id和辅id匹配它们的id和offset,简而言之,故障转移之后,连接到一个新的主实例的从实例不需要执行一个全量同步。

故障转移之后改变replication id的原因在于

由于一些分区,有可能旧的主实例仍然作为主实例在工作,保留相同的replication id违背了一个相同id和相同offset意味着它们具有相同的数据集的规则。

 只读从实例

自从2.6版本,从实例默认支持只读模式,可以通过配置文件中修改slave-read-only来设置,也可以通过命令行config set来设置,前者永久生效。但这并不意味着redis从实例就是严格的不能写,因为一些管理命令,比如DEBUG/CONFIG仍然可以使用,可以通过rename-command指令来关闭相关命令以提高安全性。从实例也可以配置为可写,但在4.0版本之前,可写从实例不能兼容expire命令,也即是,使用expire或者其他命令设置一个key的ttl最大值,当key到达了指定时间之后,使用读命令已经不能获取到key,但是通过dbsize等命令获取key的数量时,依然包含了该key并且该key依然在占用内存。redis 4.0 RC3之后版本解决了该问题,并且可写从实例可以和主实例一样可以通过ttl剔除过期数据。

自从redis4.0,从实例仅本地可写,但子从实例始终都是从主实例同步数据,如

A -- >B --> C

上述A为主实例,B为可写从实例,C为只读从实例,C中的数据内容将与A一致,C不会不同在B中写入,但在A中不存在的数据。

Redis复制处理expires

redis使用三种技术来使expire key生效

1、从实例不过期key,他们等待主实例key过期,当主实例key过期,生成一个DEL命令,发送给从实例。

2、由于主控驱动过期,有时可能主实例还没有能够提供DEL命令,从实例中还存在逻辑上已经失效的key,此时如果将该key返回给客户端,这就与逻不符。为了解决这个问题,从实例在不违法数据集一致性的情况下,使用它的逻辑时钟一遍报告一个key并不只存在于读取操作中(?),这样,从实例可以避免上报逻辑上已经过期的key仍然存在。

3、Lua脚本执行期间,不执行key过期,所以整个脚本执行期间,要么一个key不存在,要么一个key一直存在,防止key在脚本执行中间过期。

消息和角色命令

INFO

INFO REPLICATION

ROLE

 

posted @ 2019-04-01 19:16  大坑水滴  阅读(2622)  评论(0编辑  收藏  举报