引言
Redis,作为一种开源的、基于内存的数据结构存储系统,被广泛应用于各种场景,包括缓存、消息队列、短期存储等。
单一实例的工作模式通常无法保证Redis的可用性和拓展性,Redis提供了三种分布式方案:
1. Redis主从模式
1.1 什么是主从模式?
主从模式,是redis集群最基本的模式,主库负责读写,从库负责读。主库的数据会同步到从库,但是从库写的数据不会自动同步到主库,除非用写脚本等方式手动同步。这种模式应急能力比较差,假如出现宕机的情况,需要手动进行修改
1.2 全量同步
补充细节:
-
Redis4.0之前的版本,slave给master传的不是master_replid,而是runid,但是runid每次实例重启都会改变,也就是会进行一次全量同步,所以Redis4.0版本后采用replid
-
master进行bgsave生成RDB文件时,因为bgsave命令是异步的,所以在同步时候,可能会接收其它指令,所以这些指令会先暂存在一个内存空间replication_buffer,等到slave加载完RDB文件后,再同步给slave
-
设置replication_buffer大小可以通过如下进行配置
1.3 增量同步
有全量同步就会有增量同步的,那么redis什么时候会进行增量同步?增量同步的流程是怎么样的?
在全量同步时候说过,master会给slave一个偏移量offerset,如果出现slave跟master网络断开一小会等情况,导致偏移量跟master差了一点,网络恢复,slave重新跟master连接后,这时slave会发送指令,判断是否需要增量同步还是全量同步?
-
master会判断slave传过来的master_replid是否一致,如果一致,满足条件,进行下一步校验
-
增量同步会根据偏移量offerset和积压缓存数据来判断,增量同步会去积压缓存replication_backlog_buffer获取数据,如果偏移量只差了3条数据,同时在积压缓存里查找得到,就会进行增量同步
补充细节:
repl-backlog-size 1mb
1.4 主从模式的工作原理
在主从模式下,主节点负责处理所有的写操作,并将写操作记录在内存中的缓冲区。从节点从主节点获取这些写操作记录,并在自己的数据库上执行这些操作,从而保持与主节点的数据一致。此外,读请求可以在主节点和从节点上进行,从而实现读写分离,提高系统的读取性能。
具体的同步步骤如下:
-
-
发送SYNC命令:从服务器连接到主服务器后,它会发送一个SYNC命令。这个命令是Redis复制的核心,它会触发主服务器开始复制过程。
-
主服务器开始保存数据:收到SYNC命令后,主服务器会开始在后台保存其数据快照。同时,主服务器还会记录从接收到SYNC命令开始执行的所有写命令,这些命令将在数据快照完成后发送给从服务器。
-
主服务器发送数据快照:数据快照完成后,主服务器会将其发送给从服务器。从服务器在接收到数据快照后,会删除所有旧数据,然后使用接收到的数据快照来加载新数据。
-
主服务器发送缓存的写命令:数据快照发送完成后,主服务器会将在数据快照过程中记录的所有写命令发送给从服务器。从服务器在接收到这些命令后,会按照接收的顺序执行这些命令,以确保其数据与主服务器的数据保持一致。
-
主从同步完成,进入命令转发阶段:完成上述步骤后,主从服务器的数据就同步了。之后,主服务器每执行一次写命令,就会将这个命令发送给所有的从服务器。从服务器在接收到写命令后,会执行这个命令,以确保其数据始终与主服务器的数据保持一致。
2. Redis哨兵模式
2.1 什么是哨兵模式?
Redis的主从模式是可以解决负载、数据备份等问题,但是,如果master宕机的情况,slave是不会自动升级为master的,必须手动升级,所以就有了哨兵集群的方案,以及后面介绍的cluster集群
先看看官网对Sentinel的介绍
大概意思是Redis Sentinel在不适用Cluster集群的时候,为Redis提供了高可用性,并且提供了检测、通知、自动故障转移、配置提供等功能
监控 :能够监控我的redis实例是否正常运行
通知:如果redis的实例出现问题,能够通知给其它实例以及其它Sentinel
自动故障转移:master宕机,slave可以自动升级为master
总而言之,Sentinel是于Redis服务的单独服务,并且它们之间是相互通信的,可以画图表示一下Redis的哨兵模式:
2.2 哨兵模式的工作原理
在哨兵模式下,哨兵节点会定期检查主节点和从节点的运行状态。如果发现主节点发生故障,哨兵节点会在从节点中选举出一个新的主节点,并通知其他的从节点和哨兵节点。此外,哨兵节点还可以接收客户端的查询请求,返回当前的主节点信息,从而实现客户端的透明切换。
Sentinel主要负责三个方面的任务:
-
监控:通过发送命令,不间断的监控Redis服务器运行状态,包括主服务器和从服务器。
-
提醒:当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
-
自动故障迁移(核心任务):当哨兵监测到主服务器宕机,会自动在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器将其转换为主服务器(自动切换)。然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
3. Reids 集群模式
3.1 什么是Redis Cluster模式?
redis的哨兵模式提供了比如监控、自动故障转移等高可用方案,但是这种方案,容量相对固定,要进行持续扩容或者数据分片就不适合,所以有另外一种更复杂的集群方案,Cluster集群模式。
Cluster集群模式,Cluster模式支持多主多从,这种模式,按照key进行虚拟槽位分配,使得key分配到不同的主节点,使用这种模式使得集群节点有更大的容量,也可以持续进行扩容,如果主库节点出现宕机,也会从从库节点选出一个新的主库节点
所以,如果redis的数据量不是很大,就可以使用哨兵模式,如果Redis存储的数据量比较大,而且需要持续扩容,那么就需要选择Cluster模式
3.2 Redis Cluster特点
3.3 hash slot虚拟槽
那么如何进行数据分片?数据分片相当于数据库的分表,不同的数据放到不同的表里。数据分片就是要把不同的数据放到不同的实例里面。
所以,在Redis里面提出一个Hash槽,也可以称之为虚拟槽的概念。什么是虚拟槽?其实就是虚拟节点,Redis Cluster中有16384个虚拟槽。
key和虚拟槽怎么对应?会根据CRC16取模16383得到一个0到16383的值,计算公式是:slot = CRC16(key) & 16383,通过这个公式计算得到的值就表示key在哪个虚拟槽,举例:
set k1 1:
CRC16(k1) & 16383 = 10
set k2 1:
CRC16(k1) & 16383 = 5468
set k3 1:
CRC16(k1) & 16383 = 10988
# 所以k1、k2、k3对应的槽位分别是10、5468、10988
如果有3台主库,对应的槽位分别为
master1 0-5460虚拟槽
master2 5461-10922虚拟槽
master3 10923-16383虚拟槽
则,k1、k2、k3分别会放在master1、master2、master3
3.4 集群模式的工作原理
在集群模式下,Redis使用一种叫做哈希槽的技术来实现数据的分片。整个哈希空间被分成16384个哈希槽,每个节点负责一部分哈希槽。当一个键需要被存储时,Redis会根据键的值计算出一个哈希值,然后根据哈希值决定将这个键存储在哪个节点上。这样,读写请求就可以在多个节点上并行处理,提高了系统的性能。
在Redis集群模式下,任意一个Master节点都可以接受客户端的请求。当客户端向某个Master节点发送请求时,如果这个请求的键所对应的哈希槽不在这个Master节点负责的范围内,那么这个Master节点会返回一个重定向信息,告诉客户端应该向哪个节点发送请求。这个过程对客户端来说是透明的,客户端只需要按照重定向信息重新发送请求即可。这种方式确保了Redis集群可以有效地处理并分发客户端的请求,提高了系统的性能和可用性。