Redis单机的吞吐是有上限的,在一些高并发业务场景下,我们需要对Redis进行扩展。例如,实现读写分离,缓解主服务器的压力。
Replication
Redis提供了replication模式来实现主从复制。
replication主要依赖于以下三个机制:
- 当master和slave连接正常时,matser向slave发送命令来保持slave的更新,包括数据的写入,过期,逐出
- 当slave与master的连接断开,slave重新连接之后,slave会尝试进行增量同步①,只更新连接中断期间的数据
- 当slave无法执行增量同步时,会执行全量同步②
(1) 增量同步
slave 由于某些原因与 master 断开连接,重新连接之后,只需要同步着期间缺少的数据
(2) 全量同步
master 执行 BGSAVE
指令,完成后将快照文件传输给 slave
Replication特点
Redis的replication有以下特点需要了解:
- Redis使用异步复制,主从之间异步的确认数据同步的数量
- 一个主可以有多个从
- 从还可以有从。从4.0版本开始,所有的从将会从master接受到完全一样的数据①
- 复制在主服务器上是异步的,这意味着主可以在给多台从服务器器同步时还可以处理客户端的请求
- 复制在从服务器上也是异步的,如果从服务器在复制期间有客户端请求,从服务器将会从旧的数据集中返回数据。可以在配置项中进行配置
- 复制可以用于扩展读请求(实现读写分离)
- 可以使用复制来避免将全部数据写入磁盘的开销②
(1) 从服务器的数据只会从最原始的主服务器获得
例如,A --> B --> C,存在这样一条主从链,B设置为可以进行写入操作,那么C不会获得B中写入的数据,只能获得A中的数据集
(2) 不推荐这么做,在主从重新连接时,从服务器的数据如果没办法进行增量同步,将会删除本地所有的数据,再同步主服务器上的数据,所以最好还是开启持久化
配置
slaveof <masterip> <masterport>
masterauth <master-password>
slave-serve-stale-data yes # 是否异步复制
slave-read-only yes
repl-diskless-sync no # 无盘复制
repl-diskless-sync-delay 5
repl-ping-slave-period 10
repl-timeout 60
repl-disable-tcp-nodelay no
repl-backlog-size 1mb
repl-backlog-ttl 3600
slave-priority 100
min-slaves-to-write 3
min-slaves-max-lag 10
-
slaveof <masterip> <masterport>
设置从哪台Redis服务器同步数据 -
masterauth <master-password>
设置master的密码 -
slave-serve-stale-data
在同步数据时是否异步处理客户端请求① -
slave-read-only
是否开启只读,默认yes
开启 -
repl-diskless-sync
是否开启无盘复制②,默认为no
-
repl-diskless-sync-delay
无盘复制延时,默认为5
,单位秒(s) -
repl-ping-slave-period
slave 发送ping的时间间隔,默认为10
,单位秒(s) -
repl-timeout
复制超时时长,默认60
,单位秒(s) -
repl-disable-tcp-nodelay
是否在同步完成之后禁用TCP_NODELAY
,默认为no
-
repl-backlog-size
backlog 体积,默认1mb
-
repl-backlog-ttl
backlog 过期时长,默认3600
,单位秒(s) -
slave-priority
从服务器权重③ -
min-slaves-to-write
④达到指定从服务器个数才开启写入功能,设置为0表示禁用此项,默认情况下为0 -
min-slaves-max-lag
从服务器最大滞后时间,如果超过该时长,将关闭写入功能 ,默认为10
(1) 异步复制的同时处理客户端请求
Redis可能会从旧的数据集中返回数据给客户端,如果没有旧的数据集则返回空
(2) 无盘复制
子进程直接通过网络将RDB文件发给slave,不用使用磁盘作为中间存储
(3) slave-priority
在Redis的哨兵中,检测Redis可用性,如果master不可用,哨兵将会依据此项来选取从服务器提升为主服务器
(4) 达到N个从服务才开启写入查询
由于Redis的异步复制,无法保证slave接收到数据,这将存在一段丢失数据的窗口期。
slave每秒向master发送ping,确认处理的数据量,master会记录每个slave最后一次ping的时间,通过配置min-slaves-to-write N
和 min-slaves-max-lag M
来控制master的写入查询, 如果至少有N个slave,滞后小于M秒,master则接受写入;如果不满足条件,则返回error。
这是一种尽力保证数据安全的机制。其中对于给定的写入不确保一致性,但是至少数据丢失的时间窗口被限制为给定的秒数。通常,绑定数据丢失优于未绑定数据丢失。
工作机制
-
slave
启动,仅仅保存master
的信息,包括master
的host和ip,但是复制流程没开始(master的host和ip是通过redis.conf里面的slaveof配置的) -
slave
内部有个定时任务,每秒检查是否有新的master
要连接和复制,如果发现,就跟master
建立socket网络连接 -
slave
发送ping命令给master
- 口令认证,如果master设置了requirepass,那么
slave
必须发送masterauth
的口令过去进行认证 -
master
第一次执行全量复制,将所有数据发给slave node -
master
后续持续将写命令,异步复制给slave
从服务器怎么处理过期key
从服务器并不会主动过期数据集中的数据,主服务器在数据过期或被逐出的时候会向从服务器发送一条del的命令,将从服务器中对应的数据删除
什么时候执行全量同步,什么时候执行增量同步?
要理解全量,增量同步的机制,先要理解Redis复制中的三个概念:
- Replication ID(复制ID),标记数据集的给定历史记录。每次实例从头开始作为主服务器重新启动,或者从服务器提升为主服务器时,将为此实例生成新的复制ID。连接到主服务器的从服务器将在握手后继承其复制ID。
- offset(偏移量),每个主服务器还会为生成的每个复制流字节递增一个偏移量,以便将其发送到从服务器,从服务器也会保存这个值。
- backlog(缓冲区),从服务器断开与主服务器的连接之后,主服务器会暂时将数据存入backlog,默认1mb,有过期时间。
master
给slave
复制数据时,也会将数据在backlog中同步写一份,backlog主要是用来做全量复制中断候的增量复制的
从服务器由于某些原因断开与主服务器的连接,再次连接后,从服务器上报当前的Replication ID
和 offset
,如果Replication ID
不一致则进行全量同步,如果一致则判断 offset
,这区间的数据如果还存在 backlog
中,就进行 增量同步,否则进行全量同步。(从节点执行 psync
,master 返回 FULLRESYNC runid offset
进行全量同步,CONTINUE
进行增量同步)
更多详细资料参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。