咱们知道Redis是一款优秀的内存数据库,大多数场景下,咱们使用Redis做为分布式内存缓存使用,但也有部分高并发高性能场景,直接选用Redis存储数据,这就对Redis的持久化及高可用提出了要求。html
每一个Redis master拥有一个replication ID,而且每一个master记录一个offset而且在每一个byte数据流发给slave时保持递增。redis
当slave链接到master时,slave利用PSYNC命令将其旧master的replication ID和当前处理到的offset发给master,若是master校验没有问题,master将只发送增量的部分。可是,若是master的backlog队列中没有足够的缓存,或者slave在请求的是一个未知的历史的offset,这时会发生一个全量同步。数据库
所谓的全量同步,其实就是指的master节点上发生bgsave并产生一个RDB文件,与此同时申请一个buffer保存全部的新命令,当RDB文件生成完毕后,master会开始发送这个文件给slave,slave将其保存在本地磁盘并load这个文件到内存。而后master开始发送全部buffer里面保存的命令给slave执行。缓存
这里顺便提一下SYNC命令,它与PSYNC的不一样就是它不是部分的,它每次执行都是一个全量的同步,在后续版本已经不使用了,可是为了兼容性,保留了命令行的调用方式。bash
实际上每一个节点拥有两个replication IDs: main ID和secondary ID。 replication ID用来标记当前数据集的版本,每次一个实例做为master启动或者slave晋升做为一个master,会生成一个新的replication ID。slave在链接master以后,会继承master节点的replication ID,因此两个实例若是拥有相同的replication ID,而且offset相同,则说明他们当前的数据相同。并发
那么为何每一个节点有两个replication IDs呢,由于当发生failover,某个slave晋升为master,此时其余的slaves会以旧的replication ID来请求同步,这时晋升的slave,也就是新master是知道旧master的replication ID的,它用secondary ID做为main ID,也就是继承了旧master的replication ID,得以保障主从复制能够继续。less
先看一下配置异步
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
#
# A client is immediately disconnected once the hard limit is reached, or if
# the soft limit is reached and remains reached for the specified number of
# seconds (continuously).
normal 0 0 0
slave 256mb 64mb 60
pubsub 32mb 8mb 60
复制代码
意思是若是slave缓冲区的大小超过256mb,或该缓冲区的大小超过64mb而且持续60s,会马上断开slave的链接。slave在repl-timeout时间后发现没有同步任何数据,从新发起PSYNC同步请求。分布式
相关配置以下:函数
# The following option sets the replication timeout for:
#
# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
# 2) Master timeout from the point of view of slaves (data, pings).
# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
#
# It is important to make sure that this value is greater than the value
# specified for repl-ping-slave-period otherwise a timeout will be detected
# every time there is low traffic between the master and the slave.
repl-timeout 60
# Set the replication backlog size. The backlog is a buffer that accumulates
# slave data when slaves are disconnected for some time, so that when a slave
# wants to reconnect again, often a full resync is not needed, but a partial
# resync is enough, just passing the portion of data the slave missed while
# disconnected.
#
# The bigger the replication backlog, the longer the time the slave can be
# disconnected and later be able to perform a partial resynchronization.
#
# The backlog is only allocated once there is at least a slave connected.
repl-backlog-size 1mb
repl-backlog-ttl 3600
复制代码
role:master
connected_slaves:1
slave0:ip=172.16.13.128,port=9720,state=online,offset=7885515926852,lag=1
master_replid:e44c50848619ddcf19dc140466519e8309727c81
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:7885516112507
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:7885515063932
repl_backlog_histlen:1048576
复制代码
1)主节点的bgsave操做,会给主节点带来一个短期的性能抖动,缘由Redis的主进程调用fork函数时是一个同步操做,主进程会等待fork函数返回才继续执行后面的代码,当内存较大时,fork的返回时间会变长。 优化:因为fork函数的执行时间与内存使用量及机型有关,因此控制单个节点的内存大小就很关键,咱们的事件是控制单个节点的maxmemory为8GB,这样能够有效控制bgsave的fork调用产生的性能抖动。 2)写RDB文件时,会产生磁盘IO,也会带来性能的消耗。 优化:对于从节点这个性能消耗能够忽略,因此能够关闭主节点的bgsave,并在从节点开启。可是前面提到的全量同步时发生bgsave生成的RDB文件,在某些磁盘压力大的系统下会致使糟糕的性能表现,因此在2.8.18版本之后,开始支持不须要落盘的全量同步模式。具体参考配置项:repl-diskless-sync及repl-diskless-sync-delay
bgsave原理是使用操做系统的fork函数,产生一个子进程,子进程拥有当前主进程的内存快照(实际上不是复制了所有的内存内容而是基于COW),父进程经过COW(Copy On Write)技术操做内存,在修改前将修改的page页进行拷贝,再行修改,这样就不会影响子进程看到的内存内容,子进程就能够异步的将内存中的数据序列化并写入磁盘。
在复制一个对象的时候并非真正的把原先的对象复制到内存的另一个位置上,而是在新对象的内存映射表中设置一个指针,指向源对象的位置,并把那块内存的Copy-On-Write位设置为1.
这样,在对新的对象执行读操做的时候,内存数据不发生任何变更,直接执行读操做;而在对新的对象执行写操做时,将真正的对象复制到新的内存地址中,并修改新对象的内存映射表指向这个新的位置,并在新的内存位置上执行写操做。
这个技术须要跟虚拟内存和分页同时使用,好处就是在执行复制操做时由于不是真正的内存复制,而只是创建了一个指针,于是大大提升效率。但这不是一直成立的,若是在复制新对象以后,大部分对象都还须要继续进行写操做会产生大量的分页错误,得不偿失。因此COW高效的状况只是在复制新对象以后,在一小部分的内存分页上进行写操做。
传统的fork函数直接把全部资源复制给新的进程,效率很低下。 写时拷贝在须要写入时,数据才会被复制,没有数据写入时,fork()的开销实际只是复制父进程的页表以及给子进程建立惟一的进程描述符。有数据要写入前,会将将要改变的数据页复制给子进程。
详细参考:www.cnblogs.com/biyeymyhjob…
redis.io/topics/pers… redis.io/topics/repl… www.cnblogs.com/lukexwang/p… www.cnblogs.com/biyeymyhjob…