1 复制


默认情况下,处于复制模式下的主服务器可以执行读写操作,而从服务器只能执行读操作。如下图:

没有启用复制功能的Redis服务器可以执行读写操作

启用了复制功能的主服务器可以执行读写操作,但从服务器只能执行读操作
Redis的复制功能可以从性能,安全性和可用性3个方面提升整个Redis系统
性能:给系统的读性能带来线性级别的提升,理论上每增加一倍数量的服务器,系统性能就提升一倍
安全性:增加服务器数量可以降低系统在遭遇灾难故障时丢失数据的可能性
可用性:同时使用Redis的复制和Sentinel功能,可以为系统提供高可用特性
2 REPLICAOF:将服务器设置为从服务器
SLAVEOF 命令从5.0开始将替换成REPLICAOF,在未来版本中SLAVEOF命令可能会被废除
2.1 命令行
127.0.0.1:6380> REPLICAOF 127.0.0.1 6379OK
2.2 配置项设置从服务器
REPLICAOF <host> <port>
当然也可以通过启动服务器时将其设置为从服务器
redis-server --port 10086 --replicaof 127.0.0.1 6379
2.3 取消复制
127.0.0.1:6382> REPLICAOF no oneOK
说明:服务器在停止复制后不会清空数据库,而是保留复制的数据
3 ROLE:查看服务器角色
3.1 主服务器查看 ROLE 信息
127.0.0.1:6379> role1) "master" -- 服务器角色2) (integer) 5767 -- 复制偏移量(replication offset)3) 1) 1) "::1" -- 第一个从服务器IP2) "6380" -- 第一个从服务器port3) "5767" -- 复制偏移量2) 1) "::1" -- 第二个从服务器IP2) "6381" -- 第二个从服务器port3) "5767" -- 复制偏移量
说明:当从服务器复制偏移量和主服务器的一致时,那主从服务器的数据就是一致的
3.2 从服务器查看 ROLE 信息
127.0.0.1:6380> role1) "slave" -- 从服务器2) "localhost" -- 主服务器IP3) (integer) 6379 -- 主服务器PORT4) "connected" -- 主从服务器已经进入在线更新状态5) (integer) 6131 -- 复制偏移量
数组第4个元素表示从服务器与主服务器当前的连接状态
none:主从服务器尚未建立连接
connect:主从服务器正在握手
connecting:主从服务器成功建立了连接
sync:主从服务器正在进行数据同步
connected:主从服务器已经进入在线更新状态
unknown:主从服务器连接状态未知
4 数据同步
当设置一个从服务器时,主从服务器需要通过数据同步机制来让两个服务器的数据库状态保持一致
4.1 完整同步
当服务器接收到REPLICAOF命令后,就开始对另一个服务器进行复制操作。主从服务器会执行以下操作
主服务器执行BGSAVE命令生成一个RDB文件,并使用缓冲区存储起来在BGSAVE命令之后执行所有写命令
RDB文件创建完成后,主服务器会通过套接字将RDB文件传送给从服务器
从服务器接受完RDB文件后,就会载入该RDB文件,从而获得所有数据
从服务器载入RDB完成后,并开始上线处理请求时,主服务器会把之前存储的缓冲区的写命令发送给从服务器执行
之后主从服务器的状态是一致的
4.2 在线更新
主从服务器在执行完完成同步操作之后,数据就达到一致状态,但这种一致并不是永久的:每当主服务器执行了新的写命令后,它的数据库就会改变,这时主从服务器的数据一致性就会被破坏。这时Redis会对从服务器进行在线更新
每当主服务器执行完一个写命令之后,它就会将相同的命令或者具有相同效果的谢明令发送给从服务器执行。
从服务器只要执行来自主服务器的写命令,就能让自己和主服务器的数据库保持一致
异步更新引起的数据不一致
在线更新是异步执行的,所以主服务器执行完写命令后,直到从服务器也执行完相同写命令期间里,主从服务器数据会出现短暂不一致,因此要求强一致性的程序可能需要直接读取主服务器而不是从服务器
因为在线更新的异步本质,Redis复制功能是无法杜绝不一致的。
4.3 部分同步
当因故障下线的从服务器重新上线时,主从服务器数据通常不一致,因此必须重新进行同步,让主从服务器再次回到一致状态
Redis在2.8之前,重同步是通过完整同步来实现的,但这种方式是比较浪费资源的。所以从2.8开始使用新的重同步功能代替原来的重同步功能
当一个服务器称为另一个服务器主服务器时,它会把每个被执行的写命令都记录到一个特定长度的FIFO队列中
当断线从服务器尝试重新连接主服务器时,主服务器将检查从服务器断开期间,被执行的写命令是否仍然保存在队列中。如果是,那主服务器就会直接把从服务器缺失的写命令发送从服务器执行,这样避免了重新进行完整同步的麻烦
当从服务器缺失的写命令已经不存在于队列中,那主从服务器将进行一次完整同步
Redis中这个队列默认大小为1M,可以通过repl-backlog-size来修改队列大小




