单机版的redis存在三个主要问题
- 单机故障
- 容量受限
- 单机负载瓶颈,涉及socket连接数、CPU资源、IO压力等
针对这些问题redis提供了集群的方式来进行解决。在redis中有三种集群模式:主从模式、哨兵模式和Cluster集群模式。这篇文章我们来讲一下主从模式的实现原理。
架构简介
简单来说是一主多从,master做为redis的主实例,支持数据的读写,他会定时的将数据同步给slave从库。这样我们可以将大部分的读操作转移到slave从库上,在读取方面解决了单点故障问题,同时slave的可伸缩行可以降低单机负载,提高性能。
主从模式下,我们可以关闭master的持久化功能,由slave来负责持久化,这样可以绕过master的IO,大大提升性能。但需要注意,当master出现故障重启时,由于master没有可供恢复的aof或rdb文件,因此一旦重启数据会全部清除。而slave会同步master数据将本地的持久化文件也做删除。这种情况下,要关闭master的自动重启功能,避免出现类似问题。但这样仍然是很危险的,建议同时开启master和slave的持久化功能。
同步原理
在redis的主从模式中,数据同步是一个低延迟、高性能的异步处理过程。
全量同步
slave在首次成功连接到master之后会触发一次全量的同步操作,具体过程如下
- slave连接到master成功之后,发送PSYNC命令,请求master进行数据同步
- master收到同步命令fork一个子进程,并将当前的内存数据生成RDB文件,写入磁盘;同时master会接着接收写操作并保存到临时缓冲区
- master将RDB文件全量发送给slave
- slave接收并写入磁盘,然后从rdb文件加载到内存
- master将缓冲区中的所有命令发送给slave
对于master端同步过程是由子进程来处理的,因此是非阻塞的,同步期间redis仍然可接收客户端的请求。
slave端可以通过配置来控制,在同步过程中slave是否要继续接收客户端发来的请求。如果接受则允许脏数据对客户端提供,否则会返回客户端error信息。
replica-serve-stale-data yes
在数据安全性上,为了保证同步的安全性,当连接的slave数量小于m,且延迟时间小于n秒时,master认为客户端的写入操作是正确的,否则通知客户端错误。这样避免出现过多slave失联而数据不一致情况。
min-slaves-to-write 3
min-slaves-max-lag 10
全量同步时master会进行RDB写盘然后再发送到slave,这种方式是disk-back方式。它的优点是当有多个slave请求同步时,只需要生成一次RDB文件就可以服务多个slave,但对于磁盘IO较差的情况会比较糟糕。
Redis另外提供了一种方式diskless,同步时master将内存中的数据生成RDB数据后直接写入到socket字节流传给slave,而不会进行磁盘IO。很明显这种方式减少了磁盘的IO操作,需要注意的是处理过程中,其他slave的同步请求无法被处理,只能排队等待。在该模式下我们一般会设置一个时间用于master的等待,当master接收到一个同步请求时,会先进行m秒的等待,看是否有其他slave也有同步需求,对多个slave进行并行同步。
repl-diskless-sync yes
repl-diskless-sync-delay 5
增量同步
在早期的版本中,slave故障重启、断后重连master,都会导致全量的同步。高版本中对这里做了一些优化,会先尝试进行增量同步,如果不行再做一次全量同步。
具体做法是master使用一个replicationid来标记唯一的自己,同时定义一个offset偏移量表示同步处理的数据偏移量。当slave连接到master进行同步时,slave发送它记录的master的replicationid和自己处理的偏移量到master,这样master只需要查询增量数据传输给slave。
增量数据是存储在一个缓冲区中的,该缓冲区一次性分配一定的空间大小(可配),写操作命令会保存在缓冲区内。slave的增量同步会从该缓冲区查找数据,如果缓冲区设置的较大,则能支持slave断连的时间会越长。当master不存在slave且超过指定时间时,该缓冲区也会被自动释放
repl-backlog-size 1mb
repl-backlog-ttl 3600
主从模式配置
slave配置指定master的地址,开启主从模式
replicaof <masterip> <masterport>
当master需要密码校验时,从库配置密码
masterauth <master-password>
无硬盘同步模式,设置yes开启,当开启时,需要配置执行同步时要等待多少秒再开始同步
repl-diskless-sync no
repl-diskless-sync-delay 5
复制缓冲区大小
repl-backlog-size 1mb
slave不存在后多少毫秒缓冲区被释放
repl-backlog-ttl 3600
同步时master可接受写操作的slave个数和同步延迟时间
min-replicas-to-write 3
min-replicas-max-lag 10
slave同步期间是否可以对外提供服务
replica-serve-stale-data yes
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。