四、详解Redis集群

一、RDB和AOF持久化

redis的数据一般保存在内存,那么当突然宕机,岂不是数据就丢失了,因此redis实现了将数据持久化的方式:RDB和AOF两种持久化方式。

1.1 RDB持久化(bgsave)

redis支持快照的方式进行数据持久化,将redis的内存数据直接保存在磁盘上,生成RDB文件。

主要流程:主进程fork出来子进程,然后主进程继续接收用户请求,子进程开始进行数据拷贝。这里有个问题需要考虑:当子进程进行数据拷贝的时候,主进程还在接收请求,那么主进程就会在内存上进行修改,此时主子进程内存将会分离。

那么redis什么时候进行数据持久化呢,在redis中会有一些配置来设置这个频率。例如:

save 900 1
save 300 60
save 60 10000

但是RDB得缺点也很明显,如果频率太快,那么RDB执行频率高,导致性能下降。如果频率太慢,那么在中间这段时间,可能造成数据丢失。

1.2 AOF持久化

由于RDB的持久化存在数据丢失问题,因此redis在RDB的基础上,又开始支持aof模式。这中模式简单来讲就是将redis的写命令写入到一个文件中(append of file)。

 例如,当用户set一个key的时候,除了将内存中的key进行修改,还会将set命令写入到aof文件中,这样一来,即使redis宕机,那么我们也能从aof文件中将数据恢复。

那么有一个问题,redis本来是内存数据库,数据操作非常快,当加入aof的时候,却进行了io磁盘操作,这岂不是很慢?

redis中是通过aof缓冲区来解决的,当redis执行写命令的时候,将命令放入到内存缓冲区中,当到达一秒的时候(every second)将缓冲区得到数据刷入到磁盘。

1.3 AOF重写(瘦身)

由于aof文件是记录的写命令,因此随着时间的推移,aof文件将会非常大,如果aof文件过大,那么在redis重启的时候,数据恢复将会非常慢。

因此我们需要解决这个问题。

两种方案:

1、重新遍历内存,将数据重新写入一个新的aof中。

2、执行一次RDB,然后将执行过程中的写命令aof。即RDB+AOF形式。

当aof文件过大,就会执行aof重写。此时将会开辟一个新的子进程进行重写,主进程依然继续处理用户请求。子进程遍历内存,将数据以命令的形式写入新的aof中。

注意此过程主进程还依然执行,那么新的写命令怎么办呢,这里引入了【aof重写缓冲区】,新的命令将会放入这个缓冲区中,当子进程重写结束后,将aof重写缓冲区的数据在放入aof文件中。

二、Redis主从架构

之前我们讲的原理都是在redis单个机器上,单点的机器从可用性和稳定性上来说都太弱了,因此需要进行主从架构,提升系统性能,高可用。

1、在集群中启动3个实例

2、在其中两个机器下执行 slaveof或者replicateof  主ip  主port 来进行连接

通过日志可以看到,当某个机器链接主服务器的时候,主服务器打印如下日志:

其中重要的几个信息:

1、replication id

2、BGSAVE

通过这两个信息,可以看出,在主从同步的一开始,需要副本id信息和rdb文件。

同时用info命令来查看主服务器的状态:

可以看到,除了上述两个信息之外,还有两个信息:
1、offset 偏移量

2、lag 积压

2.1 主从同步原理 

2.1.1 第一次同步(全量同步)

当从节点第一次链接主节点, 主节点将会把全量数据都发送从节点。

1、首先先把master的版本发送从节点。

2、执行bgsave,将master数据快照,然后发送从节点。从节点加载RDB文件

3、master将新的操作命令放入baklog文件中,并发送到从节点中,从节点执行baklog

4、后续链接过程中,master不断将baklog里面的命令发送给slave。

那么master是如何知道slave是第一次链接呢。

这里就用到了重要的参数replication id,如果slave的replicationid和maser的不一样,则说明是第一次。

那么master是如何不断的发送baklog呢,

这里就用到了offset 偏移量,当slave的offset小于master的offset,则说明slave落后于master,需要及时同步。

2.1.2 非第一次同步(增量同步)

当slave进行重启的时候,重新链接master的时候,会发起增量同步,这个时候slave将replicationid和offset传给master。master将offset之后的数据发送给slave。

需要注意:baklog文件是一个环形,如果slave远远落后于master,那么slave将无法进行增量同步。 此时只能进行全量同步。

在这里顺便提一下:在全量同步的过程中需要rdb,所以性能可能比较慢,是否有手段来提升性能呢?

1、无磁盘复制。即在生成RDB文件的时候,不去写磁盘,而是直接写入网络io流中。【适用于磁盘满,网速快的环境】

2、控制单个redis的内存大小,这样RDB文件也不会很大

3、可以尝试利用主--从--从架构,减轻master压力

2.2 哨兵机制

redis的哨兵主要是为了检测redis主从架构的可用性。另外哨兵会协调主从之间的选举。redis的每个哨兵会不断地,间隔一秒,向主从发送ping。

主观下线:如果某个哨兵发现某个机器掉线,则认为主观下线。

客观下线:如果其他哨兵也发现机器掉线,超过了配置的阈值,则认为客观下线。

如果一旦机器被认定为客观下线,如果是主服务器挂了,则需要开始选举,那么如何选举呢。 最重要的一点是当前slave机器的offset,offset约新,则优先级越高。

这里和zk不一样,zk是自己协调,而redis是由哨兵协调,哨兵根据各个slave的offset的偏移情况,而哨兵针对主服务器的协调才和zk一样:


1. **收集候选从服务器列表**:当 Sentinel 实例们确认主服务器已经下线时,它们会开始寻找合适的从服务器作为新的主服务器。Sentinel 实例会根据从服务器的优先级、复制偏移量等因素进行评估,筛选出一个候选从服务器列表。  

2. **发起投票请求**:每个 Sentinel 实例都会向其他 Sentinel 实例发送一个包含候选从服务器列表的投票请求。投票请求中包含了每个候选从服务器的信息,如 ID、优先级、复制偏移量等。  

3. **接收并处理投票请求**:收到投票请求的 Sentinel 实例会对请求中的候选从服务器列表进行评估,然后返回自己的投票结果。每个 Sentinel 实例都可以根据自己的策略和规则来决定投给哪个候选从服务器。  

4. **统计投票结果**:发起投票请求的 Sentinel 实例会等待一段时间,收集其他 Sentinel 实例的投票结果。当超过半数的 Sentinel 实例返回投票结果时,就可以确定哪个从服务器得到了最多的票数。  

5. **选择得票最多的从服务器作为新的主服务器**:得到最多票数的从服务器将成为新的主服务器。Sentinel 实例会选择一个 Sentinel 实例作为代表,负责执行故障转移操作,将选定的从服务器转变为新的主服务器。

 6. **更新从服务器配置**:代表 Sentinel 实例会向其他从服务器发送命令,修改它们的配置,使它们指向新的主服务器。  

7. **监控新的主服务器**:故障转移完成后,Sentinel 实例会继续监视新的主服务器以及其他从服务器,确保整个集群的健康状态。

三、Redis集群架构

redis的主从模式存在一些缺点:

1、这种基于主从的模式需要主和从之间进行rdb复制,而RDB复制是一个耗性能的操作,因此一般来讲redis的内存不宜设置过大。但是如果不设置过大,那就意味着存储能力弱,如果有大量数据进行存储,那怎么办?

2、主从模式主要是为了抗住高并发的读。但是写操作还是打到主节点。如果有高并发的写操作,那该怎么办呢?

因此redis提供了集群模式。

集群模式下,由多个master构成,并且每个master都分配一定的slot。

参考:

互联网大厂技术-Redis-集群模型、架构原理、难点应用场景、高频面试问题详解_redis主观下线 客观下线-CSDN博客

相关推荐

  1. redis部署详细教程

    2024-02-19 15:48:02       45 阅读
  2. Redis() 主从、哨兵、环境搭建

    2024-02-19 15:48:02       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-19 15:48:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-19 15:48:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-19 15:48:02       82 阅读
  4. Python语言-面向对象

    2024-02-19 15:48:02       91 阅读

热门阅读

  1. C语言整理#2:常用字符串函数

    2024-02-19 15:48:02       49 阅读
  2. 【ArcGIS Pro二次开发】(80):标注_CIMLabelClass

    2024-02-19 15:48:02       42 阅读
  3. 17.1 SpringMVC框架_SpringMVC入门与数据绑定(❤❤)

    2024-02-19 15:48:02       50 阅读
  4. 代码随想录二刷——二叉树day22

    2024-02-19 15:48:02       57 阅读
  5. SpringBoot的 8 个优点

    2024-02-19 15:48:02       51 阅读
  6. 嵌入式开发之SQLite数据库

    2024-02-19 15:48:02       43 阅读
  7. 【c++每天一题】跳跃游戏

    2024-02-19 15:48:02       51 阅读
  8. php捕获Fatal error错误与异常处理

    2024-02-19 15:48:02       53 阅读
  9. SQL语句创建数据库详解

    2024-02-19 15:48:02       53 阅读