Redis(1):四种模式(单机、哨兵、集群、主从复制)原理

学习自:redis的4种模式,单机,哨兵、主从复制、集群_redis单机和集群_本郡主是喵的博客-CSDN博客

深入理解Redis的单机、主从、哨兵、集群四种模式

Redis四种部署模式(原理、优缺点及解决方案)_redis高可用方案以及优缺点_少年做自己的英雄的博客-CSDN博客

 

下一节:Redis(2):四种模式(单机、哨兵、集群、主从复制)部署

为什么redis被称为redis服务器?

因为redis在运行时是被注册为一个进程(服务),我们将其称为redis服务器

1、单机模式

安装redis,启动服务后,默认单机模式

特点:只有一个redis服务器(主服务器),但哨兵模式默认开启(只是挂掉后,没有能选举的)。


redis将数据存储于单个节点上,这个节点包括一个Redis进程和一个持久化存储单机模式非常适合小型应用程序或者开发和测试环境,因为它提供了一个简单的方法来存储和检索数据,同时具有低延迟和高性能。

缺点

  • 单点宕机会引起服务的灾难、数据丢失;
  • 单点服务器内存瓶颈,无法无限纵向扩容

2、主从模式

主从模式在单机模式的基础上增加了数据备份的功能。在主从模式中,redis节点被分为主节点和从节点。主节点负责处理所有写操作(也可以读)从节点复制(同步)主节点的数据,并负责处理读操作(只能读)。

优点

提高了可靠性和可扩展性,如果主节点故障,可以用从节点来恢复数据,将从节点手动升级为主节点继续服务。

缺点

从节点不能,如果主节点挂掉则整个服务失去写的能力,仅具备读操作,需要运维手动升级,在此过程中会出现请求失败数据丢失。

解决方案

升级为哨兵模式,可以将slave自动升级为master

2.1、主从复制

从master复制数据到slave,数据复制是单向进行的。

每台服务器默认情况下都是master,如果要变成slave需要在配置文件中单独配置,才会从默认的master转变为slave。一个master可以有0或多个slave,而每个slave只能有一个master。

2.1.1、复制原理

  • s第一次连接m,执行一次全量复制
  • 全量复制数据量过大时,会造成很大的网络开销;
  • 增量复制用于主从复制中因网络原因造成的数据丢失场景,当s再次连接上m,且该m就是原来的m,如果条件允许,m会补发数据给s,补发量比较少,避免全量复制的开销(最终是否复制由offset和buffer决定
  • 如果s再次连上的是新m,那么进行的就是全量复制
  • 早期redis只有全量复制,增量复制是2.8版本以后提供的,是对全量复制的优化

2.1.1.1、全量复制

  • s给m发送一个sync同步命令
  • m通过bgsave命令fork子进程,持久化生成RDB文件
  • m通过网络RDB文件传给s
  • s将清空老数据,载入新的RDB文件,此时s阻塞,无法响应客户端,专心复制

2.1.1.2、增量复制

  • 主从节点各自维护自己的复制偏移量offset,当m写入时,offset=offset+命令字节长度s收到m也会增加自己的offset,并同步给mm同时维护自己和s的offset,以此判断主从节点数据是否一致;
  • m指令记录在本地buffer异步将buffer同步给s
  • 若网络不好,同步速度慢了,buffer满了就会从头开始覆盖前面的内容,此时不能增量复制,必须全量复制

2.2、读写分离

为什么将读放在s,写放在m?

因为读操作占绝大多数,这样做可以减缓服务器压力;同时一些执行耗时比较久的操作也可以放在一台s完成,例如keys、sort

至于什么时间连m写,什么时间从s读,由客户端决定

最低配置

一主二从,当m宕机后,其中一个s升级为m,还能剩一个s。

主从模式是实现哨兵和集群的基础。

 

3、哨兵模式(Sentinel,2.8版本后)

在主从模式的基础上,添加了故障检测自动故障转移功能。在哨兵模式下,一个或多个哨兵进程监视redis节点运行状态。如果主节点故障,哨兵会检测到该情况并自动将其中一个从节点提升为新的主节点。这一过程是自动的不需要人为干预

哨兵模式提高了redis集群的可靠性,确保即使主节点发生故障,Redis服务也能继续运行。

如果哨兵挂了怎么办?哨兵一般是一个集群,一般由3-5个节点组成,即使个别节点挂了,集群还能正常运行。

优点

  • 可以在m挂掉后重新选举产生新的m

缺点

  • m挂掉了,切换新的m会造成未来得及主从同步的数据丢失
  • 大数据高并发,单个m内存仍存在上限
  • 主从全量同步仍要耗费大量时间
  • 单个redis只能利用CPU单个核心,难以应对海量数据

解决方案

  • 集群

3.1、一个m挂掉后整个系统的变化

 

客户端连接redis时,会首先连接sentinel(哨兵,下文简写为sen),通过sen查询m地址,再连接m进行数据交互。当m挂掉,客户端重新跟sen要m地址,连接新的m

上图中,m挂掉,原先的主从复制断开,客户端和m也断开,之后一个s成为新的m,和其余的s进行新的主从复制。客户端通过新m继续交互,sen持续监控已经挂掉的旧m,一旦旧m恢复,集群变为下图,旧m成为新s,从新m建立主从复制关系。

要点

  • 一个sensen集群可以管理多个主从redis,如果只有一个redis,那么sen将无意义
  • m挂掉,sen在s中选举一个升级为新m,并修改配置文件
  • 挂了的m恢复后,只能当s,跟新选举的m主从复制
  • sen也会挂,所以sen一般是一个集群
  • 每个sen定期检测redis数据节点、其他sen节点是否可达
  • 对于节点的故障多个sen节点共同判断防止误判
  • redis主从复制异步m挂掉,s会丢失一部分信息,sen不能保证信息完全不丢失,但尽量减少
  • Sentinel.slave_for可以从连接池内采用轮询方案拿出一个s地址,实现负载均衡

3.2、定时监控

  • 每1s,每个sen会向s、m、sen发送ping做一次心跳检测,来测试是否可达,实现对每个节点的监控
  • 每2s,每个sen会与其他sen通信,可以发现新sen节点,并与其他sen交换对m的判断信息,方便故障转移和选举
  • 每10s,每个sen会向s、m发送info命令获取最近的拓扑结构,可以感知新加入或故障转移的redis数据节点。

3.3、主观下线和客观下线

主观下线

当sen节点ping其他节点超时sen就会对该节点做失败判定

主观下线当前sen的一家之言,存在误判

客观下线

当sen主观下线的节点为msen会向其他sen询问对该m的判断,当大多数sen都对m的下线做了同意判断,那这个判断就是客观的。

3.4、Sentinel领导者选举

sen对m做了客观下线,但还不能立刻进行故障转移,因此故障转移只需要一个sen来完成,因此在sen集群中要选出一个leader进行故障转移

redis使用了raft算法来实现领导者选举

  • 每个在线的sen都有资格成为领导者,它要求其他节点来投自己一票
  • 先收到谁的要求就给谁投票,但不能给自己投
  • 先拿到大多数票(n/2+1)的当选领导者

3.4、故障转移

sen领导者负责此次故障转移:

  1. 排除主观下线的s;
  2. 选择优先级高的s,如果没有再进行3;
  3. 选择复制偏移量最大的s(复制的最完整),如果没有再进行4;
  4. 选择runid最小的s。

 

4、集群模式(3.0版本后)

集群模式是在多个Redis节点之间分配数据,提供更高的可扩展性和容错能力。

在集群模式中,数据被分配到多个Redis节点上,每个节点处理自己的数据。当一个节点失效时,集群会自动将该节点数据迁移其他节点上。集群模式在redis大规模部署中很有用,因为它可以轻松扩展和缩小redis集群,而不会影响到整个系统的性能和可靠性。

集群模式真正实现了redis高可用,有很多实现方式,目前最常用的Redis Cluster(以下简称为RC)是Redis的亲儿子,是Redis作者自己提供的Redis集群化方案,从Redis3.0版本开始正式提供。

集群由多个Redis主从组成每个主从代表一个节点每个节点负责一部分数据,它们之间通过一种特殊的二进制协议交换集群信息。

Redis Cluster将所有数据分片,分成16384个槽位RC将Key值crc16算法进行hash,然后用除留余数对模除16384得到具体槽位,每个节点负责其中一部分槽位。

客户端连接集群,会得到一部分集群的槽位匹配信息,当客户端要查找Key,可以直接定位到目标节点

Cluster去中心化,由多个节点组成客户端连接时可以只用一个节点的地址其余节点可以通过该节点自动发现,但如果该节点挂掉,就必须手动更换地址,因此连接多个地址的安全性更高。

容错

RC拥有类似哨兵功能,每个节点仍需要设置若干s当m故障时,集群可将s升级为m。

RC去中心化,当集群某个节点不可用时,一个节点认为失联不代表所有节点认为失联(主观下线与客观下线),集群要进行一次商议,只有大多数节点都认为它失联,才会认为其需要主从切换来容错

动态扩容

假设原先集群中有3个节点,一共3000条数据,可能1-1000在第一个节点,1001-2000在第二个节点,2001-3000在第三个节点。

新节点加入集群,需要手动将槽和数据迁移到新节点,可以使用redis-trib工具或手动命令迁移。

大致流程:

  • 源节点获取内容
  • 存到目标节点
  • 删除源节点内容

优点

  • 无中心架构,支持动态扩容
  • Cluster自动具备哨兵监控和故障转移(主从切换)能力
  • 客户端连接集群内地址可以自动发现
  • 高性能、高可用,有效解决了Redis分布式需求

缺点

  • 运维复杂
  • 只能用0号数据库

五、常见问题

1、Sentinel节点为什么是至少三个且奇数个?
首先必须是集群,所以不能是1个。而选举过程要大多数同意才行(即最少一半+1个),而奇数个节点在同样选举条件上可以节省一台机器。
比如一共5台,有3台同意了就行;而4台,大多数同意也要3台。
2、Redis集群节点数为什么至少是6个?
6个包含一主一从,如果每个节点一主二从则需要9个
最少3个节点,是因为容错能力相同情况下,奇数节点更节省资源(3个节点的集群允许一个节点宕机;而4个节点的集群也允许一个节点宕机)
3、为什么Redis Cluster槽位设计成16384个?
2^14=16384,当槽位再扩就是32768、65536,此时每一次ping都要将槽位作为心跳包,信息太大,占用带宽
由于集群节点越多,心跳包携带的数据就越多。当节点超过1000,会导致网络拥堵。因此Redis作者不建议Redis Cluster节点数量超过1000,那么16384槽位也足够用

下一节:Redis(2):四种模式(单机、哨兵、集群、主从复制)部署

posted @ 2023-08-10 23:47  ShineLe  阅读(606)  评论(0编辑  收藏  举报