redis复制原理和使用

INFO命令

透过info命令可以查看复制的参数和情况

$ src/redis-cli -h 192.168.56.10 -p 6381
192.168.56.10:6381> info
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.56.10,port=6379,state=online,offset=644,lag=1
master_replid:b01608293384f8ea87b5bd0aabe081948f33a3dd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:644
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:644

  

2.配置

slaveof 192.168.1.1 6379

在S端配置slaveof就足以兑现复制了,意思是自己从192.168.1.1
6379那台M复制数据。注意第五回复制的时候S上面的数量会被覆盖。下边就在自身的虚拟机上边实操一下,配置3台redis,6379是M,6380、6381是S

配置M

$ cp redis.conf redis_6379.conf
$ vi redis_6379.conf
bind 192.168.56.10 #修改ip为本机

配置S

$ cp redis_6379.conf redis_6380.conf
$ vi redis_6380.conf
#修改端口号和pid文件名
port 6380
pidfile /var/run/redis_6380.pid
slaveof 192.168.56.10 6379 #设定复制
#同样拷贝一份配置按照上面的步骤修改6381的配置
$ cp redis_6380.conf redis_6381.conf

启动

$ src/redis-server redis_6379.conf
$ src/redis-server redis_6380.conf
$ src/redis-server redis_6381.conf

测试复制

$ src/redis-cli -h 192.168.56.10 -p 6379
192.168.56.10:6379> set name pigfly
OK
192.168.56.10:6379> quit
$ src/redis-cli -h 192.168.56.10 -p 6380
192.168.56.10:6380> get name
"pigfly" #复制成功
192.168.56.10:6380> quit
$ src/redis-cli -h 192.168.56.10 -p 6379
192.168.56.10:6379> del name
(integer) 1
192.168.56.10:6379> quit
$ src/redis-cli -h 192.168.56.10 -p 6380
192.168.56.10:6380> get name
(nil) #删除同步成功

192.168.56.10:6380> set age 23
#注意S只读,这是默认配置,如果要S可写修改read-only=no
#一般来说不建议这样做,因为复制的时候会把数据覆盖
(error) READONLY You can't write against a read only slave.

192.168.56.10:6380> quit
$ src/redis-cli -h 192.168.56.10 -p 6379
192.168.56.10:6379> setex address 10 xxstreat
OK
192.168.56.10:6379> quit
$ src/redis-cli -h 192.168.56.10 -p 6380
192.168.56.10:6380> get address
(nil) #过期同步成功

 

1.前言

说到分布式高可用,必然少不了复制,一来是为着做个冗余备份幸免数据丢失,二来还足以达到疏散来加强品质的目标。基本架构:

图片 1

上边用M表示Master(主服务器),S表示Slave(从服务器),话不多说,先敲代码

 

5.参考资料

redis文档

redis实战

redis设计与达成

4.品质优化

1.调动缓冲队列的分寸来狠命达到增量复制而防止全量复制,repl-backlog-size默许1mb

 

redis复制怎么样处理过期的缓存?

  1. S不处理,而是等M处理过期后给S发送DEL命令
  2. 当M没有当即发送DEL命令,导致过期的缓存依然存在于S,S将会基于自己的逻辑时钟报告缓存已过期,并且安装为只读
  3. Lua脚本运行的时候,不实施缓存回收
  4. 假设S变身为M,它立时自个儿执行缓存回收

 

接纳Docker和NAT的情景,如何布署?

选取端口转载和互联网地址转换的时候,redis复制要越发小心,更加是行使redis-sentiner,它是按照INFO命令来收获IP地址的,这种情形下可以配备IP端口映射,来让M获取到S正确的地方:

slave-announce-ip 5.5.5.5
slave-announce-port 1234

  

那般M执行INFO命令看到S的IP就是炫耀过的:

# Replication
role:master
connected_slaves:1
slave0:ip=5.5.5.5,port=1234,state=online,offset=420,lag=1

  

3.原理

当M和S连接正常时,redis通过命令传播来一头数据,每当M执行一个写命令,就会把命令发送给S,S执行后,两者达到数据的一致性。当S第四遍再三再四或者断线后重连M的时候,复制进度是那样子的:

图片 2

其一历程也足以称之为是sync全量复制,每五次复制,M执行bgsave把持有数据打包成快照文件发给S,S再解包载入内存。

M执行bgsave消耗CPU、内存、磁盘I/O,传输进程消耗网络带宽,借使S是率先次连接M,不可幸免会履行上述操作,但即使S是断线重连的处境,就有点不划算了,因为S真正须要复制的数目是断线以后的,假诺全量复制就太浪费资源和时间了,所以redis2.8之后的本子做了革新,加了psync增量复制,psync(part-sync)跟sync不一致的是,psync只发送S真正须求的命令流,大大地增长了打包和传导的效用,那么redis是怎么落实增量复制的啊?

replid, offset

各样M和S都有地点那多少个属性,replid是M的绝无仅有标识。offset是命令流的字节数,不难的话,只要有写入命令(即便没有S),那一个offset就会追加

图片 3

M维护着上图那样一个原则性长度、先进先出的连串来保存近日的命令流

图片 4

上图就是增量复制的历程,假定S当前offset=offset_s,M当前offset=offset_m:

1.M论断replid是或不是和自己的replid相等,若是不对等,跳出执行全量复制

2.M检查offset_s是或不是还在缓冲队列,要是是,发送从offset_s开始到offset_m的命令流,倘若没有了,跳出执行全量复制

3.S推行命令流,更新offset_s = offset_m

 

复制的建制和特点:

当M和S连接杰出时,S定时请求M举办复制,M向S发送命令流来保持同步

redis默许使用高质量的异步复制,S会异步向M确认收到的数据

当M和S由于互连网难点要么逾期导致断开连接,S会尝试再次连接,请求增量复制

不可能增量复制时,执行全量复制

一个M足以有多少个S

S也得以复制其余S

复制在M端是非阻塞的,也就是M向S复制的历程中,M的查询不受影响

复制在S端也大约是非阻塞的,初叶化同步的时候,S可以提供旧数据来使查询不受影响,载入数据的时候,S将会卡住连接不提供查询服务(非凡大的数码也只须求短短几秒就一路完了),旧数据将会被删去,新数据将会被载入

能够把耗时询问放到S下面来拉长主机的品质

可以应用复制来幸免M持久化带来的支付,让一个S来持久化,可是应该幸免M重启,因为M重启之后数据是空的,这时候若是同步的话S的数码也变为空了。就终于用redis的sentinel实现的高可用方案,也休想把持久化关了,说不定sentinel还没来得及检测到故障,M就已经宕机然后重启了。为了幸免那种情形,指出M和S都开辟持久化,上边就演示数据是怎么丢失的:

  • A,B,C三台redis服务器,A是M,B和C是S
  • 因为某些原因,A宕机了,它实施活动重启机制,那时候因为关闭了持久化,磁盘里是未曾备份数据的,内存里的数目也因为重启丢失了,所以重启之后数据总体丢了
  • B和C尝试同步,它们也不管A的数量是或不是空,照常同步过来了,所以B和C的数目也丢了