redis 主从复制搭建,全量复制和部分复制

首先并不推荐手动创建redis主从,因为redis自带redis sentinel,可以使用redis sentinel来搭建主从架构,其中redis sentinel 内部实现了高可用,保证主节点或从节点挂掉可以保证服务继续!!!

优缺点

单机架构缺点
  • 机器故障,容量瓶颈,QTS瓶颈
主从复制优点
  • master ---- slave
  • 一主多从,读写分离,slave 可以还有slave

如何搭建

有两种方式一种是使用配置文件,一种是是用命令行模式,一种是配置文件形式,不管值命令行还是主从,只需要修改从节点的配置即可,主节点会自动同步从节点信息。

以一主一从为例:命令行模式(不需重启)

在这里插入图片描述

①只需要在从节点执行:
127.0.0.1:6380> slaveof 127.0.0.1 6379

②从节点查看主从信息
127.0.0.1:6380> info Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:98
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a53621985e6936091db69f9c0f404a2952e6e7b0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:98

③主节点查看主从信息
127.0.0.1:6379> info Replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=219,lag=1
master_replid:a53621985e6936091db69f9c0f404a2952e6e7b0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:219
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:219

执行下面命令
127.0.0.1:6379> set a =1
OK
127.0.0.1:6380> get a
"=1"

在从节点执行赋值,报错 (和配置文件   slave-read-only yes 有关,一般情况下,从节点不写(为了保持数据一致性,应保持默认)
从节点读)
127.0.0.1:6380> set aa 2
(error) READONLY You can't write against a read only slave

修改配置文件

①只需修改从节点配置
slaveof 127.0.0.1 6379  --- 成为某个主节点的从节点,这里ip和port是所指向的master节点

知识点:

  • run_id 和复制偏移量和复制积压缓冲区 主从复制讲的很好:点击查看

run_id 是redis每次启动时生成的随机的ID,用于标识该节点,重启会生成新的run_id,可以在redis-cli中执行 info命令查看
偏移量 用于主从同步、从节点上报从节点偏移量、master_repl_offset
主库和从库分别各自维护一个复制偏移量(可以使用info replication查看)用于标识自己复制的情况,在主库中代表主节点向从节点传递的字节数,在从库中代表从库同步的字节数。每当主库向从节点发送N个字节数据时,主节点的offset增加N,从库每收到主节点传来的N个字节数据时,从库的offset增加N。因此offset总是不断增大,这也是判断主从数据是否同步的标志,若主从的offset相同则表示数据同步量,不通则表示数据不同步
replication backlog buffer(复制积压缓冲区):复制积压缓冲区是一个固定长度的FIFO队列,大小由配置参数repl-backlog-size指定,默认大小1MB。需要注意的是该缓冲区由master维护并且有且只有一个,所有slave共享此缓冲区,其作用在于备份最近主库发送给从库的数据。在主从命令传播阶段,主节点除了将写命令发送给从节点外,还会发送一份到复制积压缓冲区,作为写命令的备份。除了存储最近的写命令,复制积压缓冲区中还存储了每个字节相应的复制偏移量(如下图),由于复制积压缓冲区固定大小先进先出的队列,所以它总是保存的是最近redis执行的命令。

主从偏移量如下图:
redis 主从复制搭建,全量复制和部分复制_第1张图片

  • 全量复制和部分复制(只讨论 2.8
全量复制流程
如果从服务器以前没有复制过任何主服务器,或者之前执行过SLAVEOF no one命令,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC ? -1命令,主动请求主服务器进行完整重同步(因为这时不可能执行部分重同步);
相反地,如果从服务器已经复制过某个主服务器,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC  命令:其中runid是上一次复制的主服务器的运行ID,而offset则是从服务器当前的复制偏移量,接收到这个命令的主服务器会通过这两个参数来判断应该对从服务器执行哪种同步操作,如何判断已经在介绍runid时进行详细说明。
根据情况,接收到PSYNC命令的主服务器会向从服务器返回以下三种回复的其中一种:

如果主服务器返回+FULLRESYNC  回复,那么表示主服务器将与从服务器执行完整重同步操作:其中runid是这个主服务器的运行ID,从服务器会将这个ID保存起来,在下一次发送PSYNC命令时使用;而offset则是主服务器当前的复制偏移量,从服务器会将这个值作为自己的初始化偏移量;
如果主服务器返回+CONTINUE回复,那么表示主服务器将与从服务器执行部分同步操作,从服务器只要等着主服务器将自己缺少的那部分数据发送过来就可以了;
如果主服务器返回-ERR回复,那么表示主服务器的版本低于Redis 2.8,它识别不了PSYNC命令,从服务器将向主服务器发送SYNC命令,并与主服务器执行完整同步操作。
   
   由此可见psync也有不足之处,当从库重启以后runid发生变化,也就意味者从库还是会进行全量复制,而在实际的生产中进行从库的维护很多时候会进行重启,而正是有由于全量同步需要主库执行快照,以及数据传输会带不小的影响。因此在4.0版本,psync命令做了改进,以下说明。

redis2.8+ 全量复制流程
redis 主从复制搭建,全量复制和部分复制_第2张图片

psync2 redis>4.0

redis4.0新版本除了增加混合持久化,还优化了psync(以下称psync2)并实现即使redis实例重启的情况下也能实现部分同步
以下常见的主从切换都可以使用部分复制:

  • 一主一从发生切换,A->B 切换变成 B->A ;
  • 一主多从发生切换,兄弟节点变成父子节点时;
  • 级别复制发生切换, A->B->C 切换变成 B->C->A;
全量复制开销~
  • bgsave时间
  • rdb文件传输时间
  • 从节点清空时间
  • 从节点加载rdb
  • 可能的AOF重写,加载rdb完成后,如果开启了aof重写,需要重写aof
部分复制
  • 如果网络发生抖动,2.8之前会重新生产rdb文件,然后重新执行
  • 之后,提供部分复制功能、如果抖动,master会在复制缓冲区生成一个buffer(默认1M),如果offset在buffer范围内,则会将部分数据复制到slave,而不需要全量复制

最后的注意事项:

  • 在上述的过程的实现是从库不开启AOF持久化情况下,如果从库开启的AOF持久化,重启时候依然使用全量复制。
  • 之前从master复制过来的数据并不会丢失,只是不再同步之前master(如上图的6379节点)后续写入的数据
  • slaveof 可以用来改变其所属的master节点,即重新成为另一台master的slave,但是新的master首先就会把从节点的数据全部清除掉
  • 关于读写分离延时: 读写分离 ,master会一步将数据复制到slave,如果slave发生阻塞,则会延迟master数据的写命令,造成数据不一致的问题。-------一般不考虑这个问题
  • 读到过期数据:redis在删除key时有两种策略,一种是懒惰型策略,即只有当redis操作这个key时才会将key删除,第二种是定期采样key删除--------当key数据非常多时,采样速度比不上key生成速度会造成很多过期数据没有删除,因为redis一般都是在master节点(增加删除数据),slave查询到过期数据也不能删除。会导致slave读到过期数据(在redis3.2中已经解决)

其他问题

  • 主从maxmemory配置不一致:导致主从数据不一致问题
  • 数据结构优化参数不一致(例如:hash-max-zip-entries):导致使用内存不一致
  • 从节点升级为主节点时会发生问题

规避全量复制优化

  • 第一次复制,无法避免~小主节点,低峰(晚上来复制)
  • 节点运行ID不匹配,主节点重启,runid会变(redis <4.0 会发生全量复制) 采用redis4.0+
  • 复制挤压缓冲区不足~增大复制缓冲区配置。修改配置文件redis.conf中的 # repl-backlog-size 1mb 默认为1M

规避复制风暴

  • 单机器复制风暴(redis<4.0当master宕机重启,会导致该机器下所有slave同时产生复制。避免单机部署一套redis主从)====》主节点分散多台机

你可能感兴趣的:(redis)