Redis的单机与三种集群模式,如何保证Redis高并发、高可用

一、 如何保证 Redis 的高并发?

Redis 通过主从集群架构,实现读写分离,主节点负责写,并将数据同步给其他从节点,从节点负责读,从而实现高并发。

如何保证Redis的高并发 - __Meng - 博客园 (cnblogs.com)

单机Redis的问题:

img

​ 单机的redis几乎不太可能说QPS超过10万+,一般在几万。

除非一些特殊情况,比如你的机器性能特别好,配置特别高,物理机,维护做的特别好,而且你的整体的操作不是太复杂。

  • 单机Redis易成为高并发的瓶颈
主从架构的Redis

img

img

​ 考虑读写分离,一般来说,对缓存,一般都是用来支撑读高并发的,写的请求是比较少的,可能写请求也就一秒钟几千,一两千;大量的请求都是读,一秒钟二十万次读。-------------------写请求较多时,是否不适用?而且这是针对缓存而言(与数据库连接,原始数据在数据库中,Redis中提供缓存)

Redis通过主从架构,实现读写分离,主节点负责写,并将数据同步给其他从节点,从节点负责读,从而实现高并发

Redis高并发的同时,还需要容纳大量的数据:一主多从,每个实例都容纳了完整的数据,比如redis主就10G的内存量,其实你就最对只能容纳10g的数据量。如果你的缓存要容纳的数据量很大,达到了几十g,甚至几百g,或者是几t,那你就需要redis集群,而且用redis集群之后,可以提供可能每秒几十万的读写并发。

redis replication的核心机制:

(1)redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量

(2)一个master node是可以配置多个slave node的

(3)slave node也可以连接其他的slave node

(4)slave node做复制的时候,是不会block master node的正常工作的

(5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了

(6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量,对于高可用性,有很大的关系

master持久化对于主从架构的安全保障的意义:

​ 如果采用了主从架构,那么建议必须开启master node的持久化!

​ 不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,slave node数据也丢了

master -> RDB和AOF都关闭了 -> 全部在内存中

master宕机,重启,是没有本地数据可以恢复的,然后就会直接认为自己的数据是空的

master就会将空的数据集同步到slave上去,所有slave的数据全部清空

100%的数据丢失

  1. master节点,必须要使用持久化机制
  2. master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的

即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障

二、如何保证Redis的高可用?

Redis 高可用,如果是做主从架构部署,那么加上哨兵就可以了,就可以实现,任何一个实例宕机,可以进行主备切换

面试题:如何保证redis的高并发及高可用? - 掘金 (juejin.cn)

如何保证Redis的高可用 - __Meng - 博客园 (cnblogs.com)

​ 如果系统在 365 天内,有 99.99% 的时间,都是能对外提供服务的,那么就说系统是高可用的。

​ 一个 slave 挂掉了,是不会影响可用性的,还有其它的 slave 在提供相同数据下的相同的对外的查询服务。但是,如果 master node 死掉了,会怎么样?没法写数据了,写缓存的时候,全部失效了。slave node 还有什么用呢,没有 master 给它们复制数据了,系统相当于不可用了。

主备切换

​ redis 的高可用架构,叫做 failover 故障转移,也可以叫做主备切换。

​ 在master故障时,自动检测,将某个slave切换为master的过程,叫做主备切换。这个过程,实现了Redis主从架构下的高可用性。

​ redis 实现高并发主要依靠主从架构,一主多从,一般来说,很多项目其实就足够了,单主用来写入数据,单机几万 QPS,多从用来查询数据,多个从实例可以提供每秒 10w 的 QPS。

​ 如果想要在实现高并发的同时,容纳大量的数据,那么就需要 redis 集群,使用 redis 集群之后,可以提供每秒几十万的读写并发。

​ redis 高可用,如果是做主从架构部署,那么加上哨兵就可以了,就可以实现,任何一个实例宕机,可以进行主备切换。

基于哨兵的高可用性

sentinel,中文名是哨兵

  • 哨兵是redis集群架构中非常重要的一个组件,主要功能如下:

(1)集群监控,负责监控redis master和slave进程是否正常工作

(2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员

(3)故障转移,如果master node挂掉了,会自动转移到slave node上

(4)配置中心,如果故障转移发生了,通知client客户端新的master地址

  • 哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作:

(1)故障转移时,判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题

(2)即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了

目前采用的是sentinel 2版本,sentinel2相对于sentinel1来说,重写了很多代码,主要是让故障转移的机制和算法变得更加健壮和简单

哨兵的核心知识:

  • 哨兵至少需要3个实例,来保证自己的健壮性
  • 哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性
  • 对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练

两种数据丢失的情况

主备切换的过程,可能会导致数据丢失

(1)异步复制导致的数据丢失

因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就宕机了,此时这些部分数据就丢失了

image-20220517102342993

(2)脑裂导致的数据丢失

脑裂(网络分区),也就是说,某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着

此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master

这个时候,集群里就会有两个master,也就是所谓的脑裂

此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master,而非新的master。

​ 因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据,导致写向旧matser的数据可能也丢失了

img

解决异步复制和脑裂导致的数据丢失

  • min-slaves-to-write 1:要求至少有1个slave
  • min-slaves-max-lag 10:数据复制和同步的延迟不能超过10秒

要求至少有1个slave,数据复制和同步的延迟不能超过10秒

如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了

上面两个配置可以减少异步复制和脑裂导致的数据丢失

(1)减少异步复制的数据丢失

有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内

img

(2)减少脑裂的数据丢失

如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求

这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失

上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求

因此在脑裂场景下,最多就丢失10秒的数据

img

三、Redis的单机与三种集群模式

一文读懂Redis的四种模式,单机、主从、哨兵、集群 - 龙跃十二 - 博客园 (cnblogs.com)

[Redis] 你了解 Redis 的三种集群模式吗? - 知乎 (zhihu.com)

redis单机版和集群版特性(学习笔记1)_等待、的博客-CSDN博客_单机redis和集群redis

1)单机版Redis

img

优点:

  • 部署简单,0成本。
  • 成本低,没有备用节点,不需要其他的开支。
  • 高性能,单机不需要同步数据,数据天然一致性。

缺点:

  • 无法高可用:靠性保证不是很好,单节点有宕机的风险。
  • 处理能力有限:单机高性能受限于CPU的处理能力,redis是单线程的。
  • 内存容量有限

单机模式选择需要根据自己的业务场景去选择,如果需要很高的性能、可靠性,单机就不太合适了。

2)主从复制模式

img

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。

前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

特点:

​ 实现读写分离,主节点负责写,并将数据同步给其他从节点,从节点负责读,从而实现高并发

​ redis replication -> 主从架构 -> 读写分离 -> 水平扩容支撑读高并发

问题:

  1. 无法保证高可用
  2. 没有解决 master 写的压力,主节点的写能力、存储能力仍然受到单机限制。

redis replication 的核心机制:

  • redis 采用异步方式复制数据到 slave 节点,不过 redis2.8 开始,slave node 会周期性地确认自己每次复制的数据量;
  • 一个 master node 是可以配置多个 slave node 的;
  • slave node 也可以连接其他的 slave node;
  • slave node 做复制的时候,不会 block master node 的正常工作;
  • slave node 在做复制的时候,也不会 block 对自己的查询操作,它会用旧的数据集来提供服务;但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了;
  • slave node 主要用来进行横向扩容,做读写分离,扩容的 slave node 可以提高读的吞吐量。

注意:

  • 如果采用了主从架构,那么建议必须开启 master node 的持久化,不建议用 slave node 作为 master node 的数据热备,因为那样的话,如果你关掉 master 的持久化,可能在 master 宕机重启的时候数据是空的,然后可能一经过复制, slave node 的数据也丢了。
  • 另外,master 的各种备份方案,也需要做。万一本地的所有文件丢失了,从备份中挑选一份 rdb 去恢复 master,这样才能确保启动的时候,是有数据的,即使采用了后续讲解的高可用机制,slave node 可以自动接管 master node,但也可能 sentinel 还没检测到 master failure,master node 就自动重启了,还是可能导致上面所有的 slave node 数据被清空。

redis 主从复制的核心原理:

  • 当启动一个 slave node 的时候,它会发送一个 PSYNC 命令给 master node。
  • 如果这是 slave node 初次连接到 master node,那么会触发一次 full resynchronization 全量复制。此时 master 会启动一个后台线程,开始生成一份 RDB 快照文件,
  • 同时还会将从客户端 client 新收到的所有写命令缓存在内存中。RDB 文件生成完毕后, master 会将这个 RDB 发送给 slave,slave 会先写入本地磁盘,然后再从本地磁盘加载到内存中,
  • 接着 master 会将内存中缓存的写命令发送到 slave,slave 也会同步这些数据。
  • slave node 如果跟 master node 有网络故障,断开了连接,会自动重连,连接之后 master node 仅会复制给 slave 部分缺少的数据。

在这里插入图片描述

过程原理

  • 当从库和主库建立MS关系后,会向主数据库发送SYNC命令
  • 主库接收到SYNC命令后会开始在后台保存快照(RDB持久化过程),并将期间接收到的写命令缓存起来
  • 当快照完成后,主Redis会将快照文件和所有缓存的写命令发送给从Redis
  • 从Redis接收到后,会载入快照文件并且执行收到的缓存的命令
  • 之后,主Redis每当接收到写命令时就会将命令发送从Redis,从而保证数据的一致

缺点

​ 所有的slave节点数据的复制和同步都由master节点来处理,会照成master节点压力太大,使用主从从结构来解决

3)哨兵模式

​ 在主从复制实现之后,如果想对 master 进行监控,Redis 提供了一种哨兵机制,哨兵的含义就是监控 Redis 系统的运行状态,通过投票机制,从 slave 中选举出新的 master 以保证集群正常运行。当主节点宕机之后,从节点是可以作为主节点顶上来,继续提供服务的。

​ 还可以启用多个哨兵进行监控以保证集群足够稳健,这种情况下,哨兵不仅监控主从服务,哨兵之间也会相互监控。

  • 主从复制的基础上,哨兵实现了自动化的故障恢复。

img

如图,哨兵节点由两部分组成,哨兵节点和数据节点:

  • 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
  • 数据节点:主节点和从节点都是数据节点。

访问redis集群的数据都是通过哨兵集群的,哨兵监控整个redis集群。

一旦发现redis集群出现了问题,比如刚刚说的主节点挂了,从节点会顶上来。但是主节点地址变了,这时候应用服务无感知,也不用更改访问地址,因为哨兵才是和应用服务做交互的

Sentinel 很好的解决了故障转移,在高可用方面又上升了一个台阶,当然Sentinel还有其他功能。

比如 主节点存活检测主从运行情况检测主从切换

说下哨兵模式监控的原理

每个Sentinel以 每秒钟 一次的频率,向它所有主服务器从服务器 以及其他Sentinel实例 发送一个PING 命令。

img

如果一个 实例(instance)距离最后一次有效回复 PING命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel标记为 主观下线

如果一个 主服务器 被标记为 主观下线,那么正在 监视 这个 主服务器 的所有 Sentinel 节点,要以 每秒一次 的频率确认 该主服务器是否的确进入了 主观下线 状态。

如果一个 主服务器 被标记为 主观下线,并且有 足够数量 的 Sentinel(至少要达到配置文件指定的数量)在指定的 时间范围 内同意这一判断,那么这个该主服务器被标记为 客观下线

在一般情况下, 每个 Sentinel 会以每 10秒一次的频率,向它已知的所有 主服务器 和 从服务器 发送 INFO 命令。

当一个 主服务器 被 Sentinel标记为 客观下线 时,Sentinel 向 下线主服务器 的所有 从服务器 发送 INFO 命令的频率,会从10秒一次改为 每秒一次。

Sentinel和其他 Sentinel 协商 主节点 的状态,如果 主节点处于 SDOWN状态,则投票自动选出新的主节点。将剩余的 从节点 指向 新的主节点 进行 数据复制

当没有足够数量的 Sentinel 同意 主服务器 下线时, 主服务器 的 客观下线状态 就会被移除。当 主服务器 重新向 Sentinel的PING命令返回 有效回复 时,主服务器 的 主观下线状态 就会被移除。

哨兵模式的优缺点

优点:

  • 哨兵模式是基于主从复制模式的,所有主从的优点,哨兵模式都具有。
  • 主从可以自动切换,系统更健壮,可用性更高。——保证高可用
  • Sentinel 会不断的检查 主服务器 和 从服务器 是否正常运行。当被监控的某个 Redis 服务器出现问题,Sentinel 通过API脚本向管理员或者其他的应用程序发送通知。
  • 自动故障迁移

缺点:

  • Redis较难支持在线扩容,对于集群,容量达到上限时在线扩容会变得很复杂。
  • 主从模式,切换需要时间,容易丢数据(重新选举出master需要时间)
  • 没有解决 master 写的压力

4)Cluster集群模式(Redis官方)

Redis Cluster是一种服务器分片 Sharding 技术,3.0版本开始正式提供。

通过数据分片的方式来进行数据共享问题,同时提供数据复制和故障转移功能。

Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在 redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容

img

背景:

​ Redis的官方多机部署方案,Redis Cluster。一组Redis Cluster是由多个Redis实例组成,官方推荐我们使用6实例,其中3个为主节点,3个为从结点。一旦有主节点发生故障的时候,Redis Cluster可以选举出对应的从结点成为新的主节点,继续对外服务,从而保证服务的高可用性。

​ 那么对于客户端来说,知道对应的key是要路由到哪一个节点呢?原来,Redis Cluster 把所有的数据划分为16384个不同的槽位,可以根据机器的性能把不同的槽位分配给不同的Redis实例,对于Redis实例来说,他们只会存储部分的Redis数据,当然,槽的数据是可以迁移的,不同的实例之间,可以通过一定的协议,进行数据迁移。

Cluster 模式的原理:

​ 其实现原理就是一致性 Hash。Redis Cluster 中有一个 16384 长度的槽的概念,他们的编号为 0、1、2、3 …… 16382、16383。这个槽是一个虚拟的槽,并不是真正存在的。正常工作的时候,Redis Cluster 中的每个 Master 节点都会负责一部分的槽,当有某个 key 被映射到某个 Master 负责的槽,那么这个 Master 负责为这个 key 提供服务

​ 至于哪个 Master 节点负责哪个槽,这是可以由用户指定的,也可以在初始化的时候自动生成(redis-trib.rb脚本)。这里值得一提的是,在 Redis Cluster 中,只有 Master 才拥有槽的所有权,如果是某个 Master 的 slave,这个slave只负责槽的使用,但是没有所有权。

Cluster 的分片机制:

​ 为了使得集群能够水平扩展,首要解决的问题就是如何将整个数据集按照一定的规则分配到多个节点上。对于客户端请求的 key,根据公式 HASH_SLOT=CRC16(key) mod 16384,计算出映射到哪个分片上。而对于 CRC16 算法产生的 hash 值会有 16bit,可以产生 2^16-=65536 个值。

​ Redis 集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容。可以说,槽是 Redis 集群管理数据的基本单位,集群伸缩就是槽和数据在节点之间的移动。

客户端如何路由?

​ 既然 Redis 集群中的数据是分片存储的,那我们该如何知道某个 key 存在哪个节点上呢?即我们需要一个查询路由,该路由根据给定的 key,返回存储该键值的机器地址。

​ 常规的实现方式便是采用如下图所示的代理方案,即采用一个中央节点(比如HDFS中的NameNode)来管理所有的元数据,但是这样的方案带来的最大问题就是代理节点很容易成为访问的瓶颈,当读写并发量高的时候,代理节点会严重的拖慢整个系统的性能。

​ Redis 并没有选择使用代理,而是客户端直接连接每个节点。Redis 的每个节点中都存储着整个集群的状态,集群状态中一个重要的信息就是每个桶的负责节点。在具体的实现中,Redis 用一个大小固定为 CLUSTER_SLOTS 的 clusterNode 数组 slots 来保存每个桶的负责节点。

方案说明

  • 通过哈希的方式,将数据分片,每个节点均分存储一定哈希槽(哈希值)区间的数据,默认分配了16384 个槽位

  • 每份数据分片会存储在多个互为主从的多节点上

  • 数据写入先写主节点,再同步到从节点(支持配置为阻塞同步)

  • 同一分片多个节点间的数据不保持一致性

  • 读取数据时,当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点

  • 扩容时时需要需要把旧节点的数据迁移一部分到新节点

  • 在 redis cluster 架构下,每个 redis 要放开两个端口号,比如一个是 6379,另外一个就是 加1w 的端口号,比如 16379。

    16379 端口号是用来进行节点间通信的,也就是 cluster bus 的东西,cluster bus 的通信,用来进行故障检测、配置更新、故障转移授权。cluster bus 用了另外一种二进制的协议,gossip 协议,用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。

分布式寻址算法:

  • hash 算法(大量缓存重建)
  • 一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡)
  • redis cluster 的 hash slot 算法

优点

  • 无中心架构,支持动态扩容,对业务透明
  • 具备Sentinel的监控和自动Failover(故障转移)能力
  • 客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • 高性能,客户端直连redis服务,免去了proxy代理的损耗

缺点:

  • 运维也很复杂,数据迁移需要人工干预
  • 只能使用0号数据库
  • 不支持批量操作(pipeline管道操作)
  • 分布式逻辑和存储模块耦合等
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中提到,哨兵模式是为了实现Redis高可用性。当一个master节点宕机时,需要大部分的哨兵节点都同意才能进行故障转移,确保系统的正常工作。即使部分哨兵节点挂掉了,哨兵集群仍然能够正常工作,因为哨兵选举流程是分布式的。\[1\] 引用\[2\]中提到,哨兵的功能包括集群监控、消息通知、故障转移和配置中心。它负责监控Redis的主节点和从节点是否正常工作,并在主节点宕机时自动将其转移到从节点上。同时,哨兵还负责通知客户端新的主节点地址,确保客户端能够正确连接到Redis集群。\[2\] 引用\[3\]中提到,Redis集群模式使用了hash slot来实现节点的增加和移除,这使得增加和移除节点的成本非常低。当增加一个主节点时,只需要将其他主节点的hash slot移动部分过去;当减少一个主节点时,只需要将其hash slot移动到其他主节点上。这种机制使得Redis集群模式具有高可用性。\[3\] 综上所述,Redis的哨兵模式集群模式都是为了实现高可用性。哨兵模式通过故障转移来保证系统的正常工作,而集群模式通过使用hash slot来实现节点的增加和移除,从而实现高可用性。 #### 引用[.reference_title] - *1* *2* *3* [Redis 哨兵模式集群模式](https://blog.csdn.net/weixin_43889841/article/details/117483197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值