Redis高可用策略与集群方案

前面几篇Redis的文章《Redis基础与入门实战》《Redis性能优化和高级用法》都是从开发的角度来介绍其在缓存上的应用,把以前需要在数据库里做的事情搬到Redis中,可以很好的提高访问并发度和数据的存取效率,但是从运维角度出发还需考虑生产环境的复杂特性,实现Redis的高并发和高可用。

一、Redis的高可用策略(主从&哨兵架构)

1. 基本概念

高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影响。 停止服务的原因可能由于网卡、路由器、机房、CPU负载过高、内存溢出、自然灾害等不可预期的原因导致,在很多时候也称单点问题。

主备方式(简单情景)
这种通常是一台主机、一台或多台备机,在正常情况下主机对外提供服务,并把数据同步到备机,当主机宕机后,备机立刻开始服务。 Redis HA中使用比较多的是keepalived,它使主机备机对外提供同一个虚拟IP,客户端通过虚拟IP进行数据操作,正常期间主机一直对外提供服务,宕机后VIP自动漂移到备机上。优点是对客户端毫无影响,仍然通过VIP操作。 缺点也很明显,在绝大多数时间内备机是一直没使用,被浪费着的。

主从方式(推荐)
这种采取一主多从的办法,主从之间进行数据同步。 当Master宕机后,通过选举算法(Paxos、Raft)从slave中选举出新Master继续对外提供服务,主机恢复后以slave的身份重新加入。 主从另一个目的是进行读写分离,这是当单机读写压力过高的一种通用型解决方案。 其主机的角色只提供写操作或少量的读,把多余读请求通过负载均衡算法分流到单个或多个slave服务器上。

缺点是主机宕机后,Slave虽然被选举成新Master了,但对外提供的IP服务地址却发生变化了,意味着会影响到客户端。 解决这种情况需要一些额外的工作,在当主机地址发生变化后及时通知到客户端,客户端收到新地址后,使用新地址继续发送新请求。

方案选择
主备(keepalived)方案配置简单、人力成本小,在数据量少、压力小的情况下推荐使用。 如果数据量比较大,不希望过多浪费机器,还希望在宕机后,做一些自定义的措施,比如报警、记日志、数据迁移等操作,推荐使用主从方式,因为和主从搭配的一般还有个管理监控中心。

2. 主从拓扑

Redis的主从拓扑支持单层或者多层结构,可分为一主一从,一主多从,树状主从。
(1).一主一从:用于主节点故障转移从节点,当主节点的“写”命令并发高且需要持久化,可以只在从节点开启AOF(主节点不需要),这样即保证了数据的安全性,也避免持久化对主节点的影响。

《Redis高可用策略与集群方案》 一主一从

(2).一主多从:针对“读”较多的场景,“读”由多个从节点来分担,但节点越多,主节点同步到多节点的次数也越多,影响带宽,也加重主节点的负担。

《Redis高可用策略与集群方案》 一主多从

(3).树状主从:一主多从的缺点(主节点推送次数多压力大)可用些方案解决,主节点只推送一次数据到从节点1,再由从节点2推送到11,减轻主节点推送的压力。

《Redis高可用策略与集群方案》 树状主从

Redis的数据同步方式

无论是主备还是主从都牵扯到数据同步的问题,这也分2种情况:

  • 同步方式:当主机收到客户端写操作后,以同步方式把数据同步到从机上,当从机也成功写入后,主机才返回给客户端成功,也称数据强一致性。 很显然这种方式性能会降低不少,当从机很多时,可以不用每台都同步,主机同步某一台从机后,从机再把数据分发同步到其他从机上,这样提高主机性能分担同步压力。 在redis中是支持这杨配置的,一台master,一台slave,同时这台salve又作为其他slave的master。
  • 异步方式:主机接收到写操作后,直接返回成功,然后在后台用异步方式把数据同步到从机上。 这种同步性能比较好,但无法保证数据的完整性,比如在异步同步过程中主机突然宕机了,也称这种方式为数据弱一致性。

3. 哨兵机制

前面介绍了主从机制,但是从运维角度来看,主节点出现了问题我们还需要通过人工干预的方式把从节点设为主节点,还要通知应用程序更新主节点地址,这种方式非常繁琐笨重, 而且主节点的读写能力都十分有限,有没有较好的办法解决这两个问题,哨兵机制就是针对第一个问题的有效解决方案,第二个问题则有赖于集群!哨兵的作用就是监控Redis系统的运行状况,其功能主要是包括以下三个:

  • 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当主数据库出现故障时自动将从数据库转换为主数据库。

《Redis高可用策略与集群方案》 一个典型使用哨兵的Redis主从架构

哨兵的原理:Redis哨兵的三个定时任务,Redis哨兵判定一个Redis节点故障不可达主要就是通过三个定时监控任务来完成的:

  • 每隔10秒每个哨兵节点会向主节点和从节点发送"info replication" 命令来获取最新的拓扑结构

《Redis高可用策略与集群方案》 哨兵获取最新拓扑结构

  • 每隔2秒每个哨兵节点会向Redis节点的_sentinel_:hello频道发送自己对主节点是否故障的判断以及自身的节点信息,并且其他的哨兵节点也会订阅这个频道来了解其他哨兵节点的信息以及对主节点的判断

《Redis高可用策略与集群方案》 哨兵的订阅与发布

  • 每隔1秒每个哨兵会向主节点、从节点、其他的哨兵节点发送一个 “ping” 命令来做心跳检测

《Redis高可用策略与集群方案》 哨兵心跳检测

如果在定时Job3检测不到节点的心跳,会判断为“主观下线”。如果该节点还是主节点那么还会通知到其他的哨兵对该主节点进行心跳检测,这时主观下线的票数超过了<quorum>数时,那么这个主节点确实就可能是故障不可达了,这时就由原来的主观下线变为了“客观下线”

故障转移和Leader选举
如果主节点被判定为客观下线之后,就要选取一个哨兵节点来完成后面的故障转移工作,选举出一个leader,这里面采用的选举算法为Raft。选举出来的哨兵leader就要来完成故障转移工作,也就是在从节点中选出一个节点来当新的主节点,这部分的具体流程可参考引用.

source:《深入理解Redis哨兵搭建及原理》

二、分布式与集群

集群时代至少部署两台Redis服务器构成一个小的集群,主要有2个目的:

  • 高可用性:在主机挂掉后,自动故障转移,使前端服务对用户无影响。
  • 读写分离:将主机读压力分流到从机上。

在Redis集群设计包括2部分:哈希Slot和节点主从

1. 节点主从

这部分实际在前面的主从拓扑中已经提及,1个Master配备有N个slaver,而且Slaver也可以有自己的Slaver,由于这种主从的关系决定他们是在配置阶段就要指定他们的上下级关系,而不是Zookeeper那种平行关系。节点主从上可以实现读写分离,Master只负责写和同步数据给Slaver,Slaver承担了被读的任务,所以Slaver的扩容只能提高读效率不能提高写效率

  • 优点:读写分离,通过增加Slaver可以提高并发读的能力。
  • 缺点:Master写能力是瓶颈。维护Slaver开销总将会变成瓶颈,同时Master的Disk大小也将会成为整个Redis集群存储容量的瓶颈。

2.哈希Slot:

说白了就像是数据库的分库分表,把整个数据按分区规则映射到多个节点,即把数据划分到多个节点上,每个节点负责整体数据的一个子集。每个Node节点被平均分配了一个Slot段,对应着0-16384,Slot不能重复也不能缺失,否则会导致对象重复存储或无法存储。Node之间也互相监听,一旦有Node退出或者加入,会按照Slot为单位做数据的迁移。

  • 优点:将Redis的写操作分摊到了多个节点上,提高写的并发能力,扩容简单。
  • 缺点:每个Node承担着互相监听、高并发数据写入、高并发数据读出,工作任务繁重

《Redis高可用策略与集群方案》 HashSlot

3.大集群时代

集群3.0时代:主从和哈希的设计优缺点正好是相互弥补的,可先Hash分逻辑节点,然后每个逻辑节点内部是主从结构,想扩展并发读就添加Slaver,想扩展并发写就添加Master,想扩容也就是添加Master,任何一个Slaver或者几个Master挂了都不会是灾难性的故障。

总结以下其优缺点:

  • 优点:无中心节点;数据按照 slot 存储分布在多个 Redis 实例上;平滑的进行扩容/缩容节点;自动故障转移(节点之间通过 Gossip 协议交换状态信息,进行投票机制完成 Slave 到 Master 角色的提升);降低运维成本,提高了系统的可扩展性和高可用性。
  • 缺点:严重依赖外部 Redis-Trib;缺乏监控管理;需要依赖 Smart Client(连接维护, 缓存路由表, MultiOp 和 Pipeline 支持);Failover 节点的检测过慢,不如“中心节点 ZooKeeper”及时;Gossip 消息的开销;无法根据统计区分冷热数据;Slave“冷备”,不能缓解读压力。

source:《三张图秒懂Redis集群设计原理》

Redis集群+Proxy
当数据量持续增加时,应用可根据不同场景下的业务申请对应的分布式集群。 这块最关键的是缓存治理这块,其中最重要的部分是加入了代理服务。 应用通过代理访问真实的Redis服务器进行读写,这样做的好处是:

  • 避免越来越多的客户端直接访问Redis服务器难以管理,而造成风险。
  • 在代理这一层可以做对应的安全措施,比如限流、授权、分片。
  • 避免客户端越来越多的逻辑代码,不但臃肿升级还比较麻烦。
  • 代理这层无状态的,可任意扩展节点,对于客户端来说,访问代理跟访问单机Redis一样。

目前有公司使用的是客户端组件和代理两种方案并存,因为通过代理会影响一定的性能。 代理这块对应的方案实现有Twitter的Twemproxy和豌豆荚的codis。

《Redis高可用策略与集群方案》 大规模分布式集群

source:《Redis面试题及分布式集群》《Redis集群架构及对比》

推荐阅读:https://blog.csdn.net/u014209205/article/details/82113258

    原文作者:YitaiCloud
    原文地址: https://www.jianshu.com/p/c2abf726acc7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞