redis复制原理同运用。redis复制原理与运用。

1.前言

说及分布式高可用,必然少不了复制,一来是以举行个冗余备份防止数据丢失,二来还好达到疏散来增长性能的目的。基本架构:

图片 1

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

 

1.前言

说交分布式高可用,必然少不了复制,一来是为了开只冗余备份防止数据丢失,二来还足以直达疏散来提高性的目的。基本架构:

图片 2

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

 

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) #过期同步成功

 

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) #过期同步成功

 

3.原理

当M和S连接正常时,redis通过命令传播来一块数据,每当M执行一个状命令,就见面管命发送给S,S执行后,两者达数的一致性。当S第一不成连续要断线后重连M的时候,复制过程是这样子的:

图片 3

是进程为堪称作是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就会见追加

图片 4

M维护着上图这样一个定点长度、先进先出的阵来保存最近底命令流

图片 5

落得图就是是增量复制的进程,假定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的数据吧废弃了

 

3.原理

当M和S连接正常时,redis通过命令传播来并数据,每当M执行一个状命令,就会见管命发送给S,S执行后,两者达数的一致性。当S第一次连续要断线后重连M的上,复制过程是这样子的:

图片 6

以此历程也可称之为是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就会大增

图片 7

M维护着上图这样一个一定长度、先进先出的排来保存最近的命令流

图片 8

达成图就是是增量复制的历程,假定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的多少也丢了

 

redis复制如何处理过的复苏存?

  1. S不处理,而是等M处理过后叫S发送DEL命令
  2. 当M没有就发送DEL命令,导致过期的缓存还有于S,S将会晤因自己的逻辑时钟报告缓存已过,并且安装为单念
  3. Lua脚本运行的下,不执行缓存回收
  4. 若果S变身为M,它就自个儿执行缓存回收

 

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

  

下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

  

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

  

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

  

4.性能优化

1.调整缓冲队排的轻重缓急来尽量达到增量复制而幸免全量复制,repl-backlog-size默认1mb

 

4.性能优化

1.调缓冲队排的深浅来尽可能达到增量复制而避免全量复制,repl-backlog-size默认1mb

 

5.参考资料

redis文档

redis实战

redis设计及落实

5.参考资料

redis文档

redis实战

redis设计以及贯彻

相关文章

admin

网站地图xml地图