欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

图形组合!一篇了解 Redis 主从复制角色和场景模式与原理的文章!

最编程 2024-06-13 19:47:42
...

目录

  1. 什么是 Redis 主从复制
  2. 主从复制的作用及场景
  3. 主从复制的模式
  • 一主一从
  • 一主多从

4.主从复制的原理

  • 全量复制
  • 部分复制
  • 总结

什么是 Redis 主从复制

总所周知 Redis 之所以火因为它有着读取速度快、可持久化的优点。Redis 的持久化保证了断电或重启数据不会丢失。但仅仅这样是不够的,持久化是将数据定期写入磁盘中,万一哪一天这一台服务器挂掉了,那所有数据依旧会丢失。为了解决这个单点故障问题,所以就有了主从复制。

主从复制就是将一台 Redis 服务器的数据自动地复制到其他 Redis 服务器上。一台服务器出故障的概率很高,但是多台服务器同时出故障的概率就很低了吧。所谓主从主从,当然是有主服务器(Master)和从服务器(Slave),一个 Master 可以将数据复制到多个 Slave,但是特别注意的是,复制是单向的,只能从 Master 到 Slave。一个 Master 可以有多个 Slave,一个 Slave 也可以有多个 Slave,但是一个 Slave 只能从属一个 Master。如下图这样就是错误的。

阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理

主从复制的作用及场景

  • 数据冗余:主从复制实现了数据的热备份,相当于一份数据在多个服务器上存储了,是持久化之外的一种数据冗余方式,这样做的目的是以空间换取安全性。如果主服务器挂掉了,可以通过从服务将数据恢复。
  • 故障快速修复:当 Master 出现问题的时候,可以快速地将一个 Slave 切换成 Master 继续提供服务,保证项目稳定性。
  • 读写分离:主从复制实现读写分离非常简单,写入的时候只操作 Master,读取的时候只操作 Slave,这样读的话可以多个 Slave 满足项目高并发的操作。
  • 负载均衡:既然实现了读写分离,当然就能实现负载均衡,多个 Slave 承担数据读取操作,从而分担 Master 服务器的压力。
  • 高可用的基石:主从复制还是哨兵模式和集群模式能够实施的基础。

既然主从复制有这些作用,那在实际应用中会用在哪些场景呢?

  • 如果项目对数据安全性稳定性要求较高,就会使用主从复制搭建哨兵模式或者搭建集群。
  • 海量数据读写,需要做读写分离提高防蚊效率,就会用到主从复制。
  • 容灾恢复,如果对数据依赖度很高,害怕数据在服务器挂掉后丢失,就可以通过主从复制防止数据丢失。

主从复制的模式

一主一从

这种模式在实际应用中还是比较少见的其实,一主一从主要是实现读写分离和容灾恢复。考虑到成本的问题,所以采用两台服务器,一个 Redis 服务器 Master 负责读操作,并定期的复制到另个一服务器 Slave。Slave 服务器负责读写操作。在项目中配置的时候配置两个 Redis 连接。

一主多从

一主多从有可以分为几种,如下图:

阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理

这种就是所有的 Slave 都从 Master 中进行复制,这样的好处是 配置简单,所有的 Slave 都只用关系 Master 就好了,但是要考虑到其实复制也是会侵占 CPU 内存的,所有的 Slave 都从 Master 复制,可能增大 Master 的负荷。

再来看看下图:

阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理
阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理

这种模式也是一主多从,但是和上面的所有的 Slave 都从 Master 复制不一样。它是使一个到两个 Slave 从 Master 直接复制,其他的 Slave 从这两个 Slave 中复制。存在层级关系。这样的好处的降低的 Master 服务器的负荷,但是这样会导致如果中间某个 Slave 挂掉了,那依附于它的所有 Slave 都不能用了。

主从复制的原理

上面以及搭建了一个主从复制的样例,是一主两从的,那是怎么 Redis 是怎么具体实现的呢?

在将原理之前,先来看看主从复制的几个概念。启动 Master 后:

127.0.0.1:6379> info server
# Server
redis_version:4.0.9
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:514e9a11b2a67dfc
redis_mode:standalone
os:Linux 5.0.0-23-generic x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:7.4.0
process_id:19688
run_id:136de716105e54294144003a881ba29cdfbccfb2
tcp_port:6379
uptime_in_seconds:4515
uptime_in_days:0
hz:10
lru_clock:5556386
executable:/usr/local/redis/etc/redis-server
config_file:/usr/local/redis/etc/redis.conf

这个 run_id 就是 Redis 服务的唯一标识,重启 Redis 服务号,这个 run_id 会改变,多个 Redis 客户端连接到同一个服务端,其 run_id 是一样的,也就是说 run_id 指的是服务端的 id:

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.252.53,port=6389,state=online,offset=5541,lag=1
slave1:ip=192.168.252.53,port=6399,state=online,offset=5541,lag=0
master_replid:f0c89aa8040dfe869de82ee623a1212240456d76
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5541
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:5541

其中 repl_backlog_size 复制缓存区大小,默认大小为 1M,如果 mater_repl_offset 在这个范围内,就看是部分复制,否则就开始全量复制。

全量复制

先看下图,图画的不是很好见谅。

阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理

  1. 首先 Slave 会向 Master 发送一个 psync 命令,因为是第一次,所以不知道 run_id 和 offset,所以传过来 -1 表示全量复制。
  2. Master 在接收到 psync 后,将 run_id 和 offset 发送给 Slave,Slave 存储起来。
  3. Master 进行 bgsave 生成 RDB,并将 RDB 文件发送给 Slave。
  4. 在 bgsave 和 send RDB 的过程中可能会产生 write 的数据,那么就会把数据存到 repl_back_buffer 中 并将 buffer 发送给 Slave。
  5. Slave 会清空就数据,然后加载 RDB 和 buffer 将数据存储起来。

部分复制

阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理

既然是部分复制,那就是 Slave 已经知道了 Master 的 run_id 和 offset,所以发送 psync 命令带上这两个参数,Master 就知道这是部分复制,然后通过偏移量将需要复制的数据发送给 Slave。

总结

主从复制的过程中既用到了全量复制也用到了部分复制,二者是相互配合使用的。看下面的流程图:

阿里Java研发二面:了解Redis主从复制?讲讲它的作用及场景原理

还有一点需要注意的是,如果 Master 重启了,那么它的 run_id 发生了改变,那么依赖它的 Slave 都会进行一次全量复制后在进行部分复制。

最后

觉得不错可以点个赞支持一下!

更多技术文章请关注微信公众号:以Java架构赢天下



推荐阅读