Redis四种部署模式(原理、优缺点及解决方案)

一、单节点模式

Redis默认启动,什么都不配置,默认就是Master节点,简单却不具备高可用。

优点

  • 配置简单,操作简单

缺点

  1. 单点的宕机引来的服务的灾难、数据丢失
  2. 单点服务器内存瓶颈,无法无限纵向扩容

解决办法

  • 单节点宕机,可以由其他节点暂时顶替,宕机的慢慢排查

二、主从模式

优点

  • 有了主从,提高了Redis整体的可用性,当主节点(master)挂了,可以把从节点(slave)手动升级为主节点继续服务。 

缺点

  • master挂了整个Redis将失去写操作的能力,仅具备读操作,需要运维半夜爬起来手动升级,中间的请求失败数据丢失无法容忍。

解决办法

  • 可以有一种方式自动升级slave为master      ------【哨兵】

2.1 主从复制

        从一台Redis服务器的数据(主节点master),复制到其他Redis服务器(从节点slave)。数据复制单向,只能由主节点到从节点,master可读可写,slave只可读不可写;默认每台Redis服务器都是主节点,从节点需要在配置文件中单独配置,才会从默认的主节点变成从节点。一个主节点可以有0个或多个从节点,但每个从节点只能有一个主节点。

2.1.1 复制原理

  • slave第一次连接master,一定会执行一次全量复制
  • 全量复制数据量过大,会造成很大的网络开销,消耗CPU/内存/硬盘IO
  • 增量复制用于处理在主从复制中因网络等数据丢失的场景,当slave再次连接上master,并且就是原来的master,如果条件允许,master补发数据给slave,补发数据量小,避免全量复制的开销(到底能不能复制还要看offset和buffer的情况)
  • 如果slave再次连上的master是新选举的master,那么只能进行全量复制
  • 早期的redis只有全量复制,增量复制是对全量复制的重大优化,尽量采用2.8以上版本

2.1.1.1 全量复制

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

2.1.1.2 增量复制

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

2.2 读写分离

        大部分情况都是读操作,将读操作放在从节点,写操作放在主节点,减缓服务器压力;同时一些执行耗时比较久的操作也可以放在一台从节点完成,例如keys、sort。(什么时候连主节点写,什么时候连从节点读,由客户端自己控制)

        最低配:一主二从,当主节点宕机后,其中一个从节点升级为主节点,还能剩一个从节点。

2.3 主要作用

  1. 数据冗余:热备份,持久化另一种方式
  2. 故障恢复:master宕机,快速升级slave为master
  3. 读写分离:master写,slave,提高服务器负载能力,同时可以根据需求添加slave
  4. 负载均衡:配合读写分离,读多写少场景,多个slave分担负载,大大提高并发
  5. 高可用基石:是实现哨兵和集群的基础

三、哨兵模式

        试想一下,如果主从模式中,大半夜主节点挂了,运维从床上迷迷糊糊爬起来,打开电脑,手动升级处理,怕不是第二天就要上头条了。

        哨兵模式的出现用于解决主从模式中无法自动升级主节点的问题,一个哨兵是一个节点,用于监控主从节点的健康,当主节点挂掉的时候,自动选择一个最优从节点升级为主节点。

        但哨兵如果挂了怎么办?于是哨兵一般都会是一个集群,是集群高可用的心脏,一般由3-5个节点组成,即使个别节点挂了,集群还可以正常运行。

优点

  • 可以在master挂掉后自动选举新的master

缺点

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

解决办法

  • Redis集群方案

        客户端连接Redis,会首先连接Sentinel,通过Sentinel查询master地址,然后再连接master进行数据交互。当master挂了,客户端重新跟Sentinel要master地址,连接新的master。

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

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

3.1 定时监控任务

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

3.2 主观下线和客观下线

主观下线

        当Sentinel节点ping其他节点,超时未回复,Sentinel节点就会对该节点做失败判定。主观下线是当前Sentinel节点的一家之言,存在误判可能

客观下线

        当Sentinel主观下线的节点是master,该Sentinel会询问其他Sentinel对master的判断,当大部分Sentinel都对master的下线做了同意判断,那么这个判断就是比较客观的

3.3 Sentinel集群的领导者选举

Sentinel节点已经对master做了客观下线,但还不能立刻进行故障转移,因为故障转移工作只需要一个Sentinel节点来完成,因此在Sentinel集群中要选出一个leader来进行故障转移。

Redis使用了Raft算法实现领导者选举:

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

3.4 故障转移

Sentinel集群领导者负责此次故障转移

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

四、 集群模式

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

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

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

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

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

容错

        Redis Cluster拥有类似哨兵的功能,每个节点仍需设置若干从节点,主节点发生故障,集群可将slave升级为master;否则如果master挂了,集群完全不可用;

        且Redis Cluster是去中心化,集群内某个节点不可用时,一个节点认为他失联并不代表所以节点都认为他失联,集群要进行一次商议,只有大多数节点认为他失联,才会认为其需要主从切换来容错。

动态扩容

        假如原先集群中有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的主从模式和哨兵模式都是用实现高可用性和数据冗余的方式。 主从模式的优点: 1. 数据冗余和高可用性:主从模式通过将数据复制到多个从节点上,实现了数据的冗余备份,当主节点发生故障时,可以快速切换到从节点。 2. 读写分离:主节点处理写操作,而从节点处理读操作,可以提高系统的读写性能。 3. 扩展性:可以通过增加从节点来扩展系统的读取能力。 主从模式的缺点: 1. 单点故障:如果主节点发生故障,需要手动进行主从切换操作。 2. 数据同步延迟:由于数据同步需要一定的时间,所以在主节点发生故障并切换到从节点时,可能会丢失一部分数据。 哨兵模式的优点: 1. 自动故障检测和切换:哨兵模式引入了哨兵节点,负责监控主节点的状态,当主节点发生故障时,会自动进行主从切换。 2. 高可用性:哨兵模式可以自动将一个从节点升级为主节点,保证系统的高可用性。 哨兵模式的缺点: 1. 配置复杂:哨兵模式需要配置哨兵节点的信息,增加了系统的复杂度。 2. 性能损耗:哨兵模式需要额外的网络通信和节点间的协调,可能会导致一定的性能损耗。 总的来说,主从模式适用于对数据一致性要求较高且可以容忍手动切换的场景,而哨兵模式适用于对高可用性要求较高且可以接受一定性能损耗的场景。选择哪种模式要根据实际需求和系统特点进行权衡。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值