当前位置:网站首页>redis主从复制

redis主从复制

2022-08-09 11:12:00 Java技术债务

目录

概念

主从复制:Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。下图为级联结构。

通过数据复制,Redis 的一个 master 可以挂载多个 slave,而 slave 下还可以挂载多个 slave,形成多层嵌套结构。所有写操作都在 master 实例中进行,master 执行完毕后,将写指令分发给挂在自己下面的 slave 节点。slave 节点下如果有嵌套的 slave,会将收到的写指令进一步分发给挂在自己下面的 slave。

通过多个 slave,Redis 的节点数据就可以实现多副本保存,任何一个节点异常都不会导致数据丢失,同时多 slave 可以 N 倍提升读性能。master 只写不读,这样整个 master-slave 组合,读写能力都可以得到大幅提升。

master 在分发写请求时,同时会将写指令复制一份存入复制积压缓冲,这样当 slave 短时间断开重连时,只要 slave 的复制位置点仍然在复制积压缓冲,则可以从之前的复制位置点之后继续进行复制,提升复制效率。

Redis 的复制分为全量同步和增量同步。

Redis 在进行全量同步时,master 会将内存数据通过 bgsave 落地到 rdb,同时,将构建 内存快照期间 的写指令,存放到复制缓冲中,当 rdb 快照构建完毕后,master 将 rdb 和复制缓冲队列中的数据全部发送给 slave,slave 完全重新创建一份数据。这个过程,对 master 的性能损耗较大,slave 构建数据的时间也比较长,而且传递 rdb 时还会占用大量带宽,对整个系统的性能和资源的访问影响都比较大。

而增量复制,master 只发送 slave 上次复制位置之后的写指令,不用构建 rdb,而且传输内容非常有限,对 master、slave 的负荷影响很小,对带宽的影响可以忽略,整个系统受影响非常小。

Redis主从同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

主从复制的特点

  1. 采用异步复制;
  2. 一个主redis可以含有多个从redis;
  3. 每个从redis可以接收来自其他从redis服务器的连接;
  4. 主从复制对于主redis服务器来说是非阻塞的,这意味着当从服务器在进行主从复制同步过程中,主redis仍然可以处理外界的访问请求;
  5. 主从复制对于从redis服务器来说也是非阻塞的,这意味着,即使从redis在进行主从复制过程中也可以接受外界的查询请求,只不过这时候从redis返回的是以前老的数据,如果你不想这样,那么在启动redis时,可以在配置文件中进行设置,那么从redis在复制同步过程中来自外界的查询请求都会返回错误给客户端;(虽然说主从复制过程中对于从redis是非阻塞的,但是当从redis从主redis同步过来最新的数据后还需要将新数据加载到内存中,在加载到内存的过程中是阻塞的,在这段时间内的请求将会被阻,但是即使对于大数据集,加载到内存的时间也是比较多的);
  6. 主从复制提高了redis服务的扩展性,避免单个redis服务器的读写访问压力过大的问题,同时也可以给为数据备份及冗余提供一种解决方案;
  7. 为了编码主redis服务器写磁盘压力带来的开销,可以配置让主redis不在将数据持久化到磁盘,而是通过连接让一个配置的从redis服务器及时的将相关数据持久化到磁盘, 不过这样会存在一个问题,就是主redis服务器一旦重启,因为主redis服务器数据为空,这时候通过主从同步可能导致从redis服务器上的数据也被清空;

主从复制的实现

  1. slave 创建与 master 的连接后,首先发送 ping 指令,如果 master 没有返回异常,而是返回 pong,则说明 master 可用。
  2. 如果 Redis 设置了密码,slave 会发送 auth $masterauth 指令,进行鉴权。当鉴权完毕,从库就通过 replconf 发送自己的端口及 IP 给 master。
  3. 接下来,slave 继续通过 replconf 发送 capa eof capa psync2 进行复制版本校验。如果 master 校验成功。从库接下来就通过 psync 将自己的复制 id、复制偏移发送给 master,正式开始准备数据同步。
  4. 主库接收到从库发来的 psync 指令后,则开始判断可以进行数据同步的方式。
  5. 对于增量复制,slave 接下来就等待接受 master 传来的复制缓冲及新增的写指令,进行数据同步。
  6. 而对于全量同步,slave 会首先进行,嵌套复制的清理工作,比如 slave 当前还有嵌套的 子slave,则该 slave 会关闭嵌套 子slave 的所有连接,并清理自己的复制积压缓冲。
  7. 然后,slave 会构建临时 rdb 文件,并从 master 连接中读取 rdb 的实际数据,写入 rdb 中。在写 rdb 文件时,每写 8M,就会做一个 fsync操作, 刷新文件缓冲。当接受 rdb 完毕则将 rdb 临时文件改名为 rdb 的真正名字。
  8. 接下来,slave 会首先清空老数据,即删除本地所有 DB 中的数据,并暂时停止从 master 继续接受数据。然后,slave 就开始全力加载 rdb 恢复数据,将数据从 rdb 加载到内存。
  9. 在 rdb 加载完毕后,slave 重新利用与 master 的连接 socket,创建与 master 连接的 client,并在此注册读事件,可以开始接受 master 的写指令了。

主从复制模式下,主服务器挂了怎么办?

redis提供了哨兵模式(高可用)

何谓哨兵模式? 通过哨兵节点进行自主监控主从节点以及其他哨兵节点,发 现主节点故障时自主进行故障转移。

哨兵模式实现原理?(2.8 版本或更高才有)

  • 三个定时监控任务:
  1. 每隔 10s,每个 S 节点(哨兵节点)会向主节点和从节点发送 info 命令获 取最新的拓扑结构
  2. 每隔 2s,每个 S 节点会向某频道上发送该 S 节点对于主节点的判断以及当 前 Sl 节点的信息, 同时每个 Sentinel 节点也会订阅该频道,来了解其他 S 节点以及它们对主节点 的判断(做客观下线依据)
  3. 每隔 1s,每个 S 节点会向主节点、从节点、其余 S 节点发送一条 ping 命令 做一次心跳检测(心跳检测机制),来确认这些节点当前是否可达
  • 主客观下线:
  1. 主观下线:根据第三个定时任务对没有有效回复的节点做主观下线处理
  2. 客观下线:若主观下线的是主节点,会咨询其他 S 节点对该主节点的判断, 超过半数,对该主节点做客观下线
  3. 选举出某一哨兵节点作为领导者,来进行故障转移。选举方式:raft 算法。每个 S 节点有一票同意权,哪个 S 节点做出主观下线的时候,就会询问其 他 S 节点是否同意其为领导者。获得半数选票的则成为领导者。基本谁先做出客 观下线,谁成为领导者。
  4. 故障转移
原网站

版权声明
本文为[Java技术债务]所创,转载请带上原文链接,感谢
https://cloud.tencent.com/developer/article/2068516