Login
网站首页 > 文章中心 > 其它

Redis集群介绍及测试思路

作者:小编 更新时间:2023-09-26 09:50:50 浏览量:116人看过

Redis集群介绍

1、主从复制

Redis单节点的数据是存储在一台服务器上的,如果服务器出现故障,会导致数据不可用,而且读写都是在同一台服务器上,请求量大时会出现I/O瓶颈.为了避免单点故障和读写不分离,Redis提供了复制功能来实现Master中的数据向Slave数据库的同步.Master可以有多个Slave节点,Slave节点也可以有Slave节点,从节点是级联结构,如下图所示:

Redis集群介绍及测试思路

主从复制工作原理

一般情况下为了让数据读写分离,Master节点用来执行写操作,Slave节点提供读操作,Master执行写操作时将变化的数据同步到Slave,其工作原理如下图所示:

Redis集群介绍及测试思路

Redis主从复制基本原理有三种:全量复制、基于长连接的命令传播、增量复制.

Redis集群介绍及测试思路

第一个阶段,是主从库之间建立连接、协商同步的过程,为全量复制做准备.具体来说,从库给主库发送psync命令,表示要进行数据同步,主库根据这个命令的参数来启动复制.psync命令包含了主库的runID和复制进度offset两个参数.

runID:是每个Redis实例启动时自动生成的一个随机ID,用来唯一标记这个实例.当从库和主库第一次复制时,因为不知道主库的runID,所以将runID设置为"?".

offset:设置为-1,表示第一次复制.

主库收到psync命令后,会用FULLRESYNC响应命令带上两个参数:主库runID和主库目前的复制进度offset,返回给从库,从库收到响应后会记录下这两个参数.FULLRESYNC响应表示第一次复制采用的全量复制,也就是说,主库会把当前所有的数据都复制给从库.

第二个阶段,主库将所有数据同步给从库,从库收到数据后,首先清空现有数据,然后在本地完成数据加载.这个过程依赖于内存快照生成的RDB文件.具体来说,主库执行bgsave命令,生成RDB文件,接着将文件发给从库.

第三个阶段,主库会把第二阶段执行过程中新接收到的写命令,再发送给从库.具体来说,当主库完成RDB文件发送后,就会把此时replication buffer中的修改和新增操作发给从库,从库再重新执行这些操作.这样一来,主从库就实现同步了.

好了,全部的全量复制的基本流程,一旦主从库完成了全量复制,它们之间就会一直维护一个网络连接,主库会通过这个连接将后续陆续收到的命令操作再同步给从库,这个过程也称为基于长连接的命令传播,可以避免频繁建立连接的开销.

增量复制核心在于repl_backlog_buffer这个缓冲区.当主从库断连后,主库会把断连期间收到的写操作命令写入replication buffer,同时也会写入repl_backlog_buffer这个缓冲区.repl_backlog_buffer是一个环形缓冲区,主库记录自己写到的位置,从库也记录自己读到的位置.主从连接恢复之后,从库首先给主库发送psync命令,并把自己当前的slave_repl_offset发给主库,主库会判断自己的master_repl_offset和slave_repl_offset之间的差距,一般来说master_repl_offset会大于slave_repl_offset.此时,主库只用把master_repl_offset和slave_repl_offset之间的命令操作同步给从库就行.

2、哨兵模式

sentinel,中文名哨兵.Redis的sentinel系统用于管理多个Redis实例,该系统主要执行以下四个任务:

①监控(Monitoring):Sentinel会不断的检查主服务器和从服务器是否正常运作.

哨兵用于实现Redis集群的高可用性,本身也是分布式的,作为一个哨兵集群去运行.Sentinel的进程之间使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器.下面分别介绍一下监控和自动故障转移的基本原理:

Sentinel集群监控原理

Redis集群介绍及测试思路

①每个 Sentinel 以每秒一次的频率向它所知的主从服务器以及其它 Sentinel 实例发送一个 PING 命令.

哨兵是如何对Slave进行监控的呢?当然是通过Master来实现的,哨兵向Master发送INFO命令,Master收到命令后便将Slave列表告诉哨兵.然后哨兵根据Slave列表信息与每一个Slave建立连接,并且根据这个连接持续监控Slave.

Sentinel集群故障自动转移

故障转移简单来说有以下三个流程:

①Sentinel系统挑选出现故障的主服务器属下的其中一个从服务器,并将选中的从服务器升级为新的主服务器.

示意图

Redis集群介绍及测试思路

故障转移

Redis集群介绍及测试思路

Redis集群介绍及测试思路

3、Cluster集群

Cluster集群模式主要有以下三个特性:

Redis集群介绍及测试思路

如上图所示,Redis集群可以看成多个主从架构组合起来的,每一个主从架构可以看成一个节点.

Redis集群数据分片原理

Key 与哈希槽映射过程可以分为两大步骤:

另外,Cluster 还允许用户强制某个 key 挂在特定槽位上,通过在 key 字符串里面嵌入 tag 标记,这就可以强制 key 所挂在的槽位等于 tag 所在的槽位.

Redis集群介绍及测试思路

Cluster集群请求路由方式

Redis集群介绍及测试思路

Redis集群介绍及测试思路

这个时候大家可能会有个疑问:哈希槽与实例之间的映射关系由于新增实例或者负载均衡重新分配导致改变了咋办?

Redis集群介绍及测试思路

ASK 错误:如果某个 slot 的数据比较多,部分迁移到新实例,还有一部分没有迁移咋办?

Redis集群介绍及测试思路

Cluster集群选举算法

①集群的配置纪元 ◆1,是一个自曾计数器,初始值 0 ,每次执行故障转移都会 ◆1.

流程如下图所示:

Redis集群介绍及测试思路

Cluster集群故障转移

Redis集群的故障转移主要有三个流程:故障检测、选主流程、故障转移,下面分别简单介绍一下.

故障检查

一个节点认为某个节点失联了并不代表所有的节点都认为它失联了.只有当大多数负责处理 slot 的节点都认定了某个节点下线了,集群才认为该节点需要进行主从切换.Redis 集群节点采用 Gossip协议来广播自己的状态以及自己对整个集群认知的改变.比如一个节点发现某个节点失联了 (PFail),它会将这条信息向整个集群广播,其它节点也就可以收到这个节点的失联信息.

如果一个节点收到了某个节点失联的数量 (PFail Count) 已经达到了集群的大多数,就可以标记该节点为确定下线状态 (Fail),然后向整个集群广播,强迫其它节点也接收该节点已经下线的事实,并立即对该失联节点进行主从切换.

选主流程

参考上一节的"Cluster集群选举算法"

当一个 Slave 发现自己的主节点进入已下线状态后,从节点将开始对下线的主节点进行故障转移.

①从下线的 Master 节点的 Slave 节点列表选择一个节点成为新主节点.

Cluster集群扩容与缩容

扩容

Redis集群主要有两种扩容方式:垂直扩容和水平扩容.

水平扩容:通过增加节点的方式来增加整个缓存系统的容量.

垂直扩容比较方便,但是受制于机制内存的限制,一个机器不可能无限增大内存, 所以到了一定阶段肯定要进行水平扩容.下面我们主要讲一下水平扩容.

①将新增节点加入集群;

缩容

如果下线的是slave,那么通知其他节点忘记下线的节点

如果下线的是master,那么将此master的slot迁移到其他master之后,通知其他节点忘记此master节点

其他节点都忘记了下线的节点之后,此节点就可以正常停止服务了

Redis集群测试思路及常见问题

1、集群功能测试

集群功能测试属于最基本的测试,是为了验证集群所提供的各种功能是否能正常使用,主要有以下方面的内容:

主从节点的数据备份是否正常

主从节点的切换功能是否正常

监控及故障转移功能是否正常

集群扩缩容功能是否正常

2、集群调优测试

集群调优测试,是为了验证集群在提供服务时,如何最大限度避免因各种异常导致数据丢失或者缓存功能失效,提前对配置进行调优或者提前预案,从而保证缓存架构设计是最优的.需要注意的点主要有:集群脑裂、缓存穿透、缓存击穿、缓存雪崩、缓存预热、缓存降级、缓存更新,下面分别介绍一下定义以及解决方案.

集群脑裂

定义

Redis集群介绍及测试思路

Redis集群介绍及测试思路

脑裂出现后带来最严重的后果就是数据丢失,为什么会出现数据丢失的问题呢?

主要原因是新主库确定后会向所有的实例发送slave of命令,让所有实例重新进行全量同步,而全量同步首先就会将实例上的数据先清空,所以在主从同步期间在原主库执行的命令将会被清空(上面场景二是同样的道理,在网络分区恢复后原主节点将被降级为从节点,并且执行全量同步导致数据丢失),所以这就是数据丢失的具体原因,如下图所示:

Redis集群介绍及测试思路

解决方案

应对脑裂的解决办法应该是去限制原主库接收请求,Redis提供了两个配置项:

①min-replicas-to-write:主库能进行数据同步的最少从库数量,否则主节点拒绝写入.

这两个配置项必须同时满足,不然主节点拒绝写入.

假设:

min-replicas-to-write=1

哨兵的down-after-milliseconds设为10s

但是,在实际应用中,真的能完全避免数据的丢失吗?我们看下面的例子:

min-replicas-to-write 置 1

所以,即使 Redis 配置了 min-replicas-to-write 和 min-replicas-max-lag,当脑裂发生时,还是无法严格保证数据不丢失,只是尽量减少数据的丢失.我们需要根据被测系统的性能、网络情况、流量情况来调优这两个参数的配置,当出现异常的时候尽可能最小的缩减数据丢失的时间.

缓存穿透

①在接口访问层对用户做校验,如接口传参、登陆状态、n秒内访问接口的次数;

如果Redis内不存在该数据,则通过布隆过滤器判断数据是否在底层数据库内;

如果布隆过滤器告诉我们该key极有可能在底层数据库内存在,那么将查询下推到底层数据库即可;

缓存击穿

延长热点key的过期时间或者设置永不过期,如排行榜,首页等一定会有高并发的接口;

缓存雪崩

事实上缓存雪崩相比于缓存击穿更容易发生,对于大多数公司来讲,同时超大并发量访问同一个过时key的场景的确太少见了,而大量key同时过期,大量用户访问这些key的几率相比缓存击穿来说明显更大.

①在可接受的时间范围内随机设置key的过期时间,分散key的过期时间,以防止大量的key在同一时刻过期;

缓存预热

缓存预热的实现方式有很多,比较通用的方式是写个批任务,在启动项目时或定时去触发将底层数据库内的热点数据加载到缓存内.

缓存降级

缓存降级是指当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,即使是有损部分其他服务,仍然需要保证主服务可用.可以将其他次要服务的数据进行缓存降级,从而提升主服务的稳定性.

降级的目的是保证核心服务可用,即使是有损的.如某年双十一的时候淘宝购物车无法修改地址只能使用默认地址,这个服务就是被降级了,这里阿里保证了订单可以正常提交和付款,但修改地址的服务可以在服务器压力降低,并发量相对减少的时候再恢复.

降级可以根据实时的监控数据进行自动降级也可以配置开关人工降级.是否需要降级,哪些服务需要降级,在什么情况下再降级,取决于大家对于系统功能的取舍.

缓存更新

缓存服务(Redis)和数据服务(底层数据库)是相互独立且异构的系统,在更新缓存或更新数据的时候无法做到原子性的同时更新两边的数据,所以呢在并发读写或第二步操作异常时会遇到各种数据不一致的问题.如何解决并发场景下更新操作的双写一致是缓存系统的一个重要知识点.

以上就是土嘎嘎小编大虾米为大家整理的相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章