Redis的集群方案

Redis的集群方案总共有3种:

1.主从同步

2.哨兵模式

3.分片集群

一.Redis的主从同步

单节点Redis的并发能力是有限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离,一般都是一主多从,主节点负责写数据,从节点负责读数据

主从同步的方式:

1.全量同步:

Redis的集群方案_第1张图片

第一步从节点执行replicaof命令建立,请求主节点数据同步,然后主节点判断是否是第一次同步,如果是第一次,则返回master的数据版本信息,然后从节点保存版本信息,然后主节点执行bgsava,生成RDB,然后发送RDB文件,从节点清空本地数据,加载RDB文件,然后从节点清空本地数据,加载RDB文件,这时候是不是就完成了主从同步呢?其实这里还是有问题的,如果主节点再进行主从同步的时候又有数据进行了修改,那这部分数据并没有同步到从节点,为了解决这个问题,引入了repl_baklog它会记录RDB期间的所有命令,然后发送repl_backlog中的命令,然后从节点执行接收到的命令。

这里还有两个问题:

(1)如何判断数据是否是第一次同步

主节点有一个replid,从节点有一个replid,当进行数据同步的时候,如果这两个节点的replid不同,那么就是第一次数据同步,第一次数据同步完后,主节点会把自己的replid发送给一份给从节点,

当进行第二次同步数据的时候,两个replid值就一样了,然后再进行数据同步的时候,就不会执行bgsave,生成RDB文件了,而是直接通过repl_baklog

(2)当进行第二次数据或者更多次数据同步的时候,如何判断应该同步那一部分新修改的数据?

我们先来介绍一个概念:offset  偏移量,随着记录在repl_baklog中的数据增多而逐渐增大,slave完成同步时也会记录在当前同步的offset,如果slave的offset小于master的offset,说明slave的数据落后于master,需要更新

举个例子再进行第一次数据同步的时候,假设主节点的offset为50,在数据同步的时候,主节点又有新的数据修改,第一次数据同步结束,从节点offset为50,但主节点offset为80.那么就会把多余的30数据进行同步

2.增量同步:

Redis的集群方案_第2张图片

二.哨兵模式:

1.含义:

哨兵模式专注于对 Redis 实例(主节点、从节点)运行状态的监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现故障自动转移和恢复,确保整个 Redis 系统的可用性

 Redis的集群方案_第3张图片

Sentinel基于心跳的机制监测服务状态,每隔1秒向集群中的每个实例发送ping命令

(1)主观下线:如果某sentinel节点发现某实例未在规定时间内响应,则认为改实例主观下线

(2)客观下线:若超过指定数量的sentinel都认为该实例主观下线,则改实例客观下线

2.哨兵选主规则:

(1)首先判断主从节点断开时间长短,如超过指定时间则排除改节点

(2)然后判断从节点的slave_priority值,越小优先级越高

(3)如果slave_prority一样,则判断slave节点的offset值,越大优先级越高

(4)最后判断slave节点的运行id大小,越小优先级越高

3.Redis集群脑裂是什么?该如何实现

集群脑裂是由于主节点和sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到主节点,所以又选出了一个从节点为主节点

Redis的集群方案_第4张图片

集群脑裂带来的问题:

客户端 写入数据还是会写到老的主节点,新节点无法同步数据,当网络恢复后,sentinel会将老的主节点将为从节点,这时再从新的主节点同步数据,就会导致数据丢失

解决:我们可以修改redis的配置,可以设置最少的从节点数量以及缩短主从数据同步的延迟时间,达不到要求就拒绝请求,可以避免大量的数据丢失

三.分片集群架构:

1.主从和哨兵可以解决高可用,高并发读的问题,但是没有解决海量数据存储问题和高并发写问题

Redis的集群方案_第5张图片

集群里有多个master,每个master保存不同数据,相较于单个master,集群能存储更多的数据

每个主节点有多个从节点

主节点之间通过ping监测彼此健康状态

客户端请求可以访问集群里任意节点,最终都会转发到正确节点

2.Redis分片集群中数据是怎么存储和读取的

Redis的集群方案_第6张图片

(1)Redis分片集群里引入了哈希槽的概念,Redis集群里有16384个哈希槽

(2)  将16384插槽到不同的实例

(3)读写数据:根据key的有效部分计算哈希值,对16384取余(有效部分,如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身作为有效部分)余数作为插槽,寻找插槽所在的实例。

四.Redis快的原因

1.内存访问

  2.单线程,避免了线程的上下文切换

3.IO多路复用

下面我们来重点讲解一下IO多路复用

Redis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,I/O多路复用模型主要就是实现了高效的网络请求

用户空间和内存空间

Redis的集群方案_第7张图片

用户空间和内核空间:

linux系统中一个进程使用的内存情况划分为两部分:内核空间、用户空间

用户空间:只能执行受限的命令,而且不能直接调用系统资源,必须通过内核提供的接口 

内核空间:可以执行特权命令,调用一切系统资源

Linux系统会在用户空间和内核空间都加入缓冲区

写数据时,把用户缓冲数据拷贝到内核缓冲区,然后写入设备

丢数据时,要从设备读取数据到内核缓冲区,然后拷贝到用户缓冲区

 这里举个例子:当我们发送一条消息给对方的时候,我们发送的消息在用户缓冲区,然后到了内核缓冲区,然后再到硬件设备(网卡),通过网卡发给对方,然后对方回的消息会通过网卡放入内核缓冲区,然后到

阻塞IO:

Redis的集群方案_第8张图片

阶段一:(1)用户进程尝试读取数据(比如网卡数据)

             (2)此时数据尚未到达,内核需要等待数据

             (3)此时用户进程处于阻塞状态

阶段二:(1)数据到达并拷贝到内核缓冲区,代表已就绪

            (2)将内核数据拷贝到用户缓冲区

            (3)拷贝过程中,用户进程依然阻塞等待

             (4)拷贝完成,用户进程阻塞解除,处理数据

非阻塞IO:

Redis的集群方案_第9张图片

阶段一:

(1)用户进程尝试读取数据(比如网卡数据)

(2)此时数据尚未到达,内核需要等待数据

(3)返回异常给用户进程

(4)用户进程拿到error后,再次尝试去读

(5)循环往复,直到数据就绪

阶段二:

(1)将内核数据拷贝到用户缓冲区

(2)拷贝过程中,用户进程仍然阻塞等待

(3)拷贝完成,用户进程解除阻塞,处理数据

  可以看到非阻塞IO模型中,用户进程在第一个阶段是非阻塞,第二个阶段是阻塞状态。虽然是非阻塞,但性能并没有得到提高,而且忙等机制会导致CPU空转,CPU使用率暴增。

IO多路复用:

是利用单个线程来同时监听多个socket,并在某个Socket可读,可写时得到通知,从而避免无效的等待,充分利用CPU资源

阶段一:

(1)  用户进程调用select,指定要监听的Socket集合

(2)内核监听对应的多个socket

(3)任意一个或多个socket数据就绪则返回readable

(4)此过程中用户进程阻塞

阶段二:

(1)用户进程找到就绪的socket

(2)依次调用recvform读取数据

(3)内核将数据拷贝到用户空间

(4)用户进程处理数据

Redis的集群方案_第10张图片

select和poll只会通知用户进程有Socket就绪,但不确定具体是那个socket,需要用户进程逐个遍历Socket来确认

epoll则会通知用户进程Socket就绪的同时,把已就绪的Socket写入用户空间。

Redis网络模型

使用I/O多路复用结合事件的处理器来应对多个Socket请求

(1)连接应答处理器

(2)命令回复处理器,在Redis6.0之后,为了提升更好的性能,使用了多线程来处理回复事件

(3)命令请求处理器,在Redis6.0之后,将命令的转换使用了多线程,增加命令转换速度,在命令执行的时候,依然是单线程

Redis的集群方案_第11张图片

        

Redis的集群方案_第12张图片 

你可能感兴趣的:(java,开发语言)