Redis 主从架构

Redis 主从架构

单机的 redis,可以承载的 QPS 大概就在上万到几万不等。对于缓存来讲,通常都是用来支撑读高并发的。所以架构作成主从(master-slave)架构,一主多从,主负责写,而且将数据复制到其它的 slave 节点,从节点负责读。全部的读请求所有走从节点。这样也能够很轻松实现水平扩容,支撑读高并发node

redis replication -> 主从架构 -> 读写分离 -> 水平扩容支撑读高并发redis

redis replication 的核心机制

  • redis 采用异步方式复制数据到 slave 节点,不过 redis2.8 开始,slave node 会周期性地确认本身每次复制的数据量;
  • 一个 master node 是能够配置多个 slave node 的;
  • slave node 也能够链接其余的 slave node;
  • slave node 作复制的时候,不会 block master node 的正常工做;
  • slave node 在作复制的时候,也不会 block 对本身的查询操做,它会用旧的数据集来提供服务;可是复制完成的时候,须要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了;
  • slave node 主要用来进行横向扩容,作读写分离,扩容的 slave node 能够提升读的吞吐量。

注意,若是采用了主从架构,那么建议必须开启 master node 的[持久化],不建议用 slave node 做为 master node 的数据热备,由于那样的话,若是你关掉 master 的持久化,可能在 master 宕机重启的时候数据是空的,而后可能一通过复制, slave node 的数据也丢了。缓存

另外,master 的各类备份方案,也须要作。万一本地的全部文件丢失了,从备份中挑选一份 rdb 去恢复 master,这样才能确保启动的时候,是有数据的,即便采用了后续讲解的[高可用机制],slave node 能够自动接管 master node,但也可能 sentinel 还没检测到 master failure,master node 就自动重启了,仍是可能致使上面全部的 slave node 数据被清空。bash

redis 主从复制的核心原理

当启动一个 slave node 的时候,它会发送一个 PSYNC 命令给 master node。网络

若是这是 slave node 初次链接到 master node,那么会触发一次 full resynchronization 全量复制。此时 master 会启动一个后台线程,开始生成一份 RDB 快照文件,同时还会将从客户端 client 新收到的全部写命令缓存在内存中。RDB 文件生成完毕后, master 会将这个 RDB 发送给 slave,slave 会先写入本地磁盘,而后再从本地磁盘加载到内存中,接着 master 会将内存中缓存的写命令发送到 slave,slave 也会同步这些数据。slave node 若是跟 master node 有网络故障,断开了链接,会自动重连,链接以后 master node 仅会复制给 slave 部分缺乏的数据。架构

主从复制的断点续传

从 redis2.8 开始,就支持主从复制的断点续传,若是主从复制过程当中,网络链接断掉了,那么能够接着上次复制的地方,继续复制下去,而不是从头开始复制一份。并发

master node 会在内存中维护一个 backlog,master 和 slave 都会保存一个 replica offset 还有一个 master run id,offset 就是保存在 backlog 中的。若是 master 和 slave 网络链接断掉了,slave 会让 master 从上次 replica offset 开始继续复制,若是没有找到对应的 offset,那么就会执行一次 resynchronizationless

若是根据 host+ip 定位 master node,是不靠谱的,若是 master node 重启或者数据出现了变化,那么 slave node 应该根据不一样的 run id 区分。异步

无磁盘化复制

master 在内存中直接建立 RDB,而后发送给 slave,不会在本身本地落地磁盘了。只须要在配置文件中开启 repl-diskless-sync yes 便可。socket

repl-diskless-sync yes

# 等待 5s 后再开始复制,由于要等更多 slave 从新链接过来
repl-diskless-sync-delay 5
复制代码

过时 key 处理

slave 不会过时 key,只会等待 master 过时 key。若是 master 过时了一个 key,或者经过 LRU 淘汰了一个 key,那么会模拟一条 del 命令发送给 slave。

复制的完整流程

slave node 启动时,会在本身本地保存 master node 的信息,包括 master node 的hostip,可是复制流程没开始。

slave node 内部有个定时任务,每秒检查是否有新的 master node 要链接和复制,若是发现,就跟 master node 创建 socket 网络链接。而后 slave node 发送 ping 命令给 master node。若是 master 设置了 requirepass,那么 slave node 必须发送 masterauth 的口令过去进行认证。master node 第一次执行全量复制,将全部数据发给 slave node。而在后续,master node 持续将写命令,异步复制给 slave node。

全量复制

  • master 执行 bgsave ,在本地生成一份 rdb 快照文件。
  • master node 将 rdb 快照文件发送给 slave node,若是 rdb 复制时间超过 60秒(repl-timeout),那么 slave node 就会认为复制失败,能够适当调大这个参数(对于千兆网卡的机器,通常每秒传输 100MB,6G 文件,极可能超过 60s)
  • master node 在生成 rdb 时,会将全部新的写命令缓存在内存中,在 slave node 保存了 rdb 以后,再将新的写命令复制给 slave node。
  • 若是在复制期间,内存缓冲区持续消耗超过 64MB,或者一次性超过 256MB,那么中止复制,复制失败。
client-output-buffer-limit slave 256MB 64MB 60
复制代码
  • slave node 接收到 rdb 以后,清空本身的旧数据,而后从新加载 rdb 到本身的内存中,同时基于旧的数据版本对外提供服务。
  • 若是 slave node 开启了 AOF,那么会当即执行 BGREWRITEAOF,重写 AOF。

增量复制

  • 若是全量复制过程当中,master-slave 网络链接断掉,那么 slave 从新链接 master 时,会触发增量复制。
  • master 直接从本身的 backlog 中获取部分丢失的数据,发送给 slave node,默认 backlog 就是 1MB。
  • master 就是根据 slave 发送的 psync 中的 offset 来从 backlog 中获取数据的。

heartbeat

主从节点互相都会发送 heartbeat 信息。

master 默认每隔 10秒 发送一次 heartbeat,slave node 每隔 1秒 发送一个 heartbeat。

异步复制

master 每次接收到写命令以后,先在内部写入数据,而后异步发送给 slave node。

redis 如何才能作到高可用

若是系统在 365 天内,有 99.99% 的时间,都是能够哗哗对外提供服务的,那么就说系统是高可用的。

一个 slave 挂掉了,是不会影响可用性的,还有其它的 slave 在提供相同数据下的相同的对外的查询服务。

可是,若是 master node 死掉了,会怎么样?无法写数据了,写缓存的时候,所有失效了。slave node 还有什么用呢,没有 master 给它们复制数据了,系统至关于不可用了。

redis 的高可用架构,叫作 failover 故障转移,也能够叫作主备切换。

master node 在故障时,自动检测,而且将某个 slave node 自动切换为 master node 的过程,叫作主备切换。这个过程,实现了 redis 的主从架构下的高可用。

后面会详细说明 redis [基于哨兵的高可用性]

相关文章
相关标签/搜索