基于MySql,Redis,Mq,ES的高可用方案解析

avatar
作者
筋斗云
阅读量:10

前言

高可用对于当下的系统而言,可以说是一个硬指标,常年专注于业务开发的我们,对于高可用最直观的感觉可能就是祈祷应用不要出问题,不要报错;即便有问题,也最好不是我们的业务代码逻辑导致的,如果是服务器、DB、中间件(如注册中心、配置中心等)的异常那就抛给对应的sre, dba;然而常在河边走,哪有不湿鞋,为了保障服务的高可用,我们可以从哪些方面进行努力呢?

本文将作为高可用的开篇,通过简述一些常用的系统的高可用方案,给大家介绍一下我们可以从哪些方面努力让我们的系统达到高可用,主要设计到的系统如下

1 redis高可用策略

redis广泛应用于缓存的业务场景,当然也有将其当做持久化存储的nosql数据库使用,这些都不重要,重点是redis在提供服务的时候,是如何支持高可用的呢?

redis官方支持了四种策略:

除以上姿势之外,我们自己在使用时还可以选择根据业务场景使用不同的redis实例(即传说中的不把所有鸡蛋放在一个篮子里)

接下来将针对redis的几种高可用策略进行简述说明

1.1 数据持久化

官方手册: Redis persistence

持久化是在高可用、一致性的场景中经常会看到的一种技术手段;

在高可用的场景中,数据的持久化主要是为了解决在服务出现问题(如宕机)之后,可以快速恢复并对外继续提供服务能力;

redis官方提供了两种持久化策略

简单来讲AOF记录的是操作动作,采用回放执行的机制进行恢复;RDB则相当于数据落盘,重新读取加载的机制进行恢复

注:AOF RDB可以一起工作,没有排他性1.2 主从方式

虽然redis性能爆炸,但是单机依然存在性能瓶颈;当我们遇到单机的性能瓶颈的时候,一般怎么做?

没错,加机器

redis也支持多机服务,比如常见的一主多从策略:

针对绝大多数读多写少的场景,我们可以起多个redis实例,其中一个设置为主,提供所有的写请求;其他的实例则设置为从,客户端通过负载策略路由到不同的从redis,从而实现流量分摊;

同时也因为有多个实例,所以单台或几台实例下线,对整个服务的可用性影响并不会太大(及时摘除故障机器,其他的实例依然可以正常提供服务;当然前提是流量所示太大把其他的实例也打挂,那就gg了)

可用高仿字大全_mysql 高可用_可用高锰酸钾洗胃的是

redis主从模式

主从模式还有一个变种,叫做从从模式,主要是为了解决主redis的同步压力,改成主 -> 从,然后由一个从同步给其他的从实例,具体架构图如下

可用高锰酸钾洗胃的是_mysql 高可用_可用高仿字大全

redis主从从模式

使用主从、主从从模式实现高可用可算是分布式系统的经典策略,其主要思想在于:

1.3 哨兵模式

官方手册: High availability with Redis Sentinel

哨兵模式主要是为了解决主从模式中,主机宕机的场景,由于主机本身存在单点,所以主节点对成了高可用的关键因素了;那么如果实现主节点宕机之后,自动选择一个新的主节点,这样不就可以提高系统的可用性了么;redis官方提供的机制就是 - 哨兵模式

主要工作原理:

可用高仿字大全_mysql 高可用_可用高锰酸钾洗胃的是

哨兵模式

哨兵模式,可以理解为探活 + 选主,而这也常见于各大分布式系统的技术方案中

1.4 集群模式

官方手册: Scaling with Redis Cluster

相比于主从模式的全量冗余,redis的集群策略在在于数据分片,每个实例上存储部分的数据;而不是全量数据,从而解决数据量大的场景下,对于redis服务本身以及数据同步的压力

集群模式的特点在于多个实例,构建成一个实例,每个实例上存储部分的数据;redis并没有采用一致性hash来做数据分布,而是使用特有的slots插槽机制,来实现数据的hash映射

mysql 高可用_可用高锰酸钾洗胃的是_可用高仿字大全

集群模式

集群模式,主要特点在于数据分片,每个实例存部分数据,其思路在于 拆分

从上面的图中也可以看出,集群一般与主从搭配使用,集群中的每个分片对应的是主从模式的redis服务,从而加强高可用

1.5 小结

这一节主要介绍的是redis的高可用策略,从中也可以看到很多经典的技术方案

看到这里的小伙伴自然会想到,为什么redis会提供这些不同的策略?它们各自的应用场景是什么,优缺点是啥?这些疑问就放在后续的redis高可用详解中介绍

相关博文:

2 MySql高可用策略

MySql数据库的高可用策略就比较多了,同样也非常的经典;仅仅主节点的保活策略就非常多了;在这里将主要的重心放在MySql的高可用架构主备、主从、一主多从,多主多从上,至于主节点故障时转移策略则放在后续详细的文章中进行介绍

2.1 数据持久化

对于每个开发者而言,大多都听说过数据库的ACID特性,其中的D对应的就是这里说到的持久化;区别于redis的持久化,以MySql的InnoDB引擎为例,其持久化涉及到多个日志文件(undo log,redo log,binlog),缓存区(buffer),磁盘(idb文件)

接下来看一下完整的数据更新/插入的流程

可用高仿字大全_mysql 高可用_可用高锰酸钾洗胃的是

mysql数据持久化流程图

接下来描述一下核心思想:

虽然上面的描述比较简单,但是这里的知识点非常多,如

undolog作用是什么,怎么支持mvcc,实现事务回滚的?redolog作用是什么,为什么两阶段方案?

更多详情内容,后面到mysql的专题时再详细介绍

2.2 主备架构

保证高可用的一个最简单策略就是“冗余”,也就是我们这里说到的主备架构,对mysql而言,就是我启动两个实例;一个主库对外提供读写服务,一个备库,冗余主库的所有数据内容,并不对外提供服务;

当主库gg之后,然后备库升级,切换为主库

话说这个思想和古代的储君制非常像了,平时都是皇帝总领朝堂,太子就当吉祥物;皇帝驾崩之后,太子就晋升为皇帝(论备胎的重要性)

可用高仿字大全_mysql 高可用_可用高锰酸钾洗胃的是

MySql主备

主备的最大特点就是多备一台实例,在出问题时顶上,当然缺点就很明显了,严重的资源浪费

2.3 主从架构

主从和前面mysql的思路差不多,主从模式一般又叫做读写分离,即写主库,读从库;相比于主备而言,最主要的突破点在于另外一个mysql实例不会干放着,而是尤其来承担读请求

可用高仿字大全_可用高锰酸钾洗胃的是_mysql 高可用

MySql主从

主从的核心思想在于读写分离

2.4 一主多从

在前面主从的基础上多挂几个从库,主要出发点在于当前的互联网场景下,绝大多数的应用都是读多写少,通过挂多个从库,可以有效提供整体服务的性能指标

同样一主多从的模式,也会区分为主从 + 主从从两种,后者则主要是为了减少主库的同步压力,下图为核心4架构模型

可用高仿字大全_可用高锰酸钾洗胃的是_mysql 高可用

MySql主从

2.5 多主多从

一主多从可以解决读多写少的场景,但总会出现写瓶颈的场景;在不考虑分库分表的业务手段之前(这种方式也可以理解为数据分片,类似上面说到的redis集群模式),仅仅从mysql的架构模式出发,自然会想到的策略就是多个主库提供写能力,这就是我们说的多主多从的架构了

可用高锰酸钾洗胃的是_mysql 高可用_可用高仿字大全

MySql主从

多主多从,其中每个主库都可以独立对外提供写请求;从库则对外提供读请求

需要注意的是主库之间的数据同步,即一个写请求落到一个任意一个主库之后,所有的主库都会同步这个写操作

2.6 主库切换策略、主从同步策略

前面介绍的是几种不同的主从架构特点,主要通过主、备/从来新增实例来提高可用性;但是还有两个非常重要的点没有细说,一个是故障之后,如何确定新的主库;另外一个则是主从/主主之间的数据如何同步,如何保证数据的一致性;

接下来我们将简单的介绍下mysql中常见的一些做法(更详细的当然留在后面的专题)

主库切换策略VIP + KeepAlived

其主要思路在于外部通过VIP访问mysql实例(主从/主主),而KeepAlived用于检测主库是否存活,当挂掉之后,VIP偏移到另外一个主库(或者选一个从库作为主库)上,从而实现自动的切主流程

缺点:

MHA

Master High Avaliable 主库高可用机制,也是当下很多公司采用的策略;其包含一套完整的工具,在检测到主库不可用后,会自动将同步到最接近主库的slave提升为master,然后将其他的slave指向新的master

其优点非常明显,通常可以实现十秒内的主从切换,扩展MySql节点也非常方便;而缺点则在于主要监控主库

MXC

PXC(Percona XtraDB Cluster)是一个完全开源的 MySQL 高可用解决方案。它将 Percona Server、Percona XtraBackup 与 Galera 库集成在一起,以实现多主复制的 MySQL 集群

其核心特点在于写请求会自动同步到其他节点,要求在所有的节点都验证之后才会提交,保证数据的强一致性

因此缺点就在于木桶效应,性能取决于最差的那个节点

MGR/InnoDB Cluste

MySQL 5.7 推出了 MGR(MySQL Group Replication),与 PXC 类似,也实现了多节点数据写入和强一致性的特点。MGR 采用 GCS(Group Communication System)协议同步数据,GCS 可保证消息的原子性

外部连接通过 MySql router与一组mysql实例进行交互,当主库切换时,mysql router会自动切换到新的主节点

Xenon

给予Raft协议的MySql高可用和复制性管理工具,无中心化选主,支持秒级切换

主从同步策略

当存在主从库时,必然会存在同步问题,如何保障主库与从库数据的一致性呢?

主从同步流程

主从同步主要借助Binlog来实现,这个在前面的图中有简单的体现,下面则是相对完整的同步流程

可用高锰酸钾洗胃的是_mysql 高可用_可用高仿字大全

MySql主从数据同步

从库的io线程拉主库的binlog日志,写入自己的relaylog(中继日志),然后由sql线程读取relaylog日志进行回放,实现数据同步主从同步策略

使用主从之后,在实际的业务开发中,最最常遇到的问题就是主从延迟,即主库数据已经写入了,但是读从库却读不到对应的数据,这个就是主从延迟了,它直接导致数据的不一致;当然一般这种影响还好,但是如果因为主从延迟,现在主库挂了,所有的从库都没有最新的记录,这不就导致数据丢失了么,会导致严重的数据一致性问题

所以在主从同步的策略上,有下面几种

case1:异步复制

主库完成写请求之后,理解返回结果,并不关心从库是否同步接收处理,此时就可能出现上面说的,主库挂了之后,所有从库还存在未同步的数据,导致数据丢失

case2:半同步复制

为了避免出现上面的问题,我们要求最少有一个从库同步完之后,才响应用户端请求,这样表明主库宕机之后还有个兜底的

case3:全同步复制

这个更激进一点,要求所有的从库都同步完,才算真正的ok,保证强一致性,缺点则在于性能会受到影响

2.7 小结

这一小节主要介绍的是MySql的高可用策略,从架构方面出发,有主备,主从,一主多从,多主多从,同时也简单的介绍了下如何实现主库的自动切换(MHA,MXC,MGR等)、主从数据同步流程,同步策略;如果想了解更详细的内容,请移步到mysql的高可用专题

下面小结一下保持高可用的主要思路

相关博文:

3. RabbitMq高可用方案

消息中间件也是大家或多或少会接触的一类系统,接下来将以RabbitMq来看一下它的高可用是如何实现的

3.1 数据持久化

不同于前面MySql必然会持久化,RabbitMq的数据持久化是可选的,当我们对数据的完整性要求高时,最好开启持久化

首先简单看一下rabbitmq的模型

可用高仿字大全_可用高锰酸钾洗胃的是_mysql 高可用

RabbitMq架构

我们这里说的持久化主要指

注意rabbitmq的消息持久化也是先写到buffer,然后再定时刷新到磁盘;

当我们为了保障数据的完整性时,一般会开启消息的确认机制/事务机制,每次投递等到mq回复一个确认ack之后,才表示真正的投递成功,而mq的应答则是在消息的持久化之后进行

3.2 主备模式

同前面的MySql的主备,主节点提供读写,备节点同步主节点的数据,不对外提供服务能力;当主节点挂了之后,启用备节点对外服务,原主节点恢复之后则作为备节点存在

3.3 Shovel远程模式

官方文档:* Shovel Plugin — RabbitMQ

远程模式可以实现双活的一种模式,简称 shovel 模式,所谓的 shovel 就是把消息进行不同数据中心的复制工作,可以跨地域的让两个 MQ 集群互联,远距离通信和复制。

可用高仿字大全_mysql 高可用_可用高锰酸钾洗胃的是

RabbitMq远程模式

如上图,有两个异地的 MQ 集群(可以是更多的集群),当用户在地区 1 这里下单了,系统发消息到 1 区的 MQ 服务器,发现 MQ 服务已超过设定的阈值,负载过高,这条消息就会被转到 地区 2 的 MQ 服务器上,由 2 区的去执行后面的业务逻辑,相当于分摊我们的服务压力。

3.4 镜像模式

如下图,用 KeepAlived 做了 HA-Proxy 的高可用,然后有 3 个节点的 MQ 服务,消息发送到主节点上,主节点通过 mirror 队列把数据同步到其他的 MQ 节点,这样来实现其高可靠

mysql 高可用_可用高仿字大全_可用高锰酸钾洗胃的是

RabbitMq镜像模式

镜像模式的主要特点在于每个mq实例都包含一份完整的数据镜像,内部有一个master选举算法,通过VIP对外提供连接

3.5 普通集群模式

exchange,buindling再所有的节点上都会保存一份,但是queue只会存储在其中的一个节点上,但是所有的节点都会存储一份queue的meta信息

如果生产者连接的是另外一个节点,将会把消息转发到存储该队列的节点上。如果消费者连接了非存储队列的节点取数据,则从存储消息的节点拉取数据。

其核心特点在于:

3.6 多活模式

这个模式我的理解也不够深刻,以下内容来自于网上摘录,待后面到rabbitmq专题之后调研后进一步阐述

rabbitMQ 部署架构采用双中心模式(多中心),那么在两套(或多套)数据中心各部署一套 rabbitMQ 集群,各中心的rabbitMQ 服务除了需要为业务提供正常的消息服务外,中心之间还需要实现部分队列消息共享

可用高仿字大全_mysql 高可用_可用高锰酸钾洗胃的是

RabbitMq镜像模式

federation 插件是一个不需要构建 cluster ,而在 brokers 之间传输消息的高性能插件,federation 插件可以在 brokers 或者 cluster 之间传输消息,连接的双方可以使用不同的 users 和 virtual hosts,双方也可以使用不同版本的 rabbitMQ 和 erlang。

federation 插件使用 AMQP 协议通信,可以接受不连续的传输。federation 不是建立在集群上的,而是建立在单个节点上的,如图上黄色的 rabbit node 3 可以与绿色的 node1、node2、node3 中的任意一个利用 federation 插件进行数据同步。

3.7 小结

rabbitmq的高可用机制的方案也比较好理解

这里采用的高可用思路也无外乎常见的几种:持久化 + 数据冗余 + 拆分

相关博文:

4. ElasticSearch高可用方案

接下来我们再看一下现在非常流行的分布式搜索引擎ElasticSearch是如何保证高可用的

4.1 集群

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎
by 官网描述

对于es而言,通常都是集群方式对外提供服务,每启动一个实例叫做一个节点(Node),每个节点会定义一个节点名(Node Name),集群名(Cluster Name),相同集群名的节点会构建为一个集群;

可用高锰酸钾洗胃的是_mysql 高可用_可用高仿字大全

ES集群

上图包含了es集群的核心要素:

选举主要流程如下

mysql 高可用_可用高仿字大全_可用高锰酸钾洗胃的是

ES选举

上面就是es集群的构建与主节点的选举过程;es支持任意节点数目的集群(1- N),无法完全依赖投票的机制来选主,而是通过一个规则。

只要所有的节点都遵循同样的规则,得到的信息都是对等的,选出来的主节点肯定是一致的。

但分布式系统的问题就出在信息不对等的情况,这时候很容易出现脑裂(Split-Brain)的问题。

大多数解决方案就是设置一个 Quorum 值,要求可用节点必须大于 Quorum(一般是超过半数节点),才能对外提供服务。而 Elasticsearch 中,这个 Quorum 的配置就是 discovery.zen.minimum_master_nodes ,当 候选主节点 的个数超过这个参数值时,开始选举,选主完成之后对外提供服务

ES作为分布式、近实时搜索系统,天然支持集群的服务能力,通过Zen Discover来实现节点通信、集群管理、选主

4.2 脑裂问题

上面提到了脑裂,接下来简单看一下ES是如何解决脑裂问题的

脑裂:由于网络或者集群健康监测问题,导致整个集群出现多个master节点,这种现象就是脑裂

es对节点进行了角色划分

一个节点,可以即是数据节点,又是候选主节点,但是注意它们两者的定位,主节点对机器性能要求没有数据节点高,当一台机器既是数据节点又是主节点时,可能出现长耗时、耗资源的请求导致主节点服务异常;

通常更推荐的方案是使用性能低一点的作为候选主节点,性能高的作为数据节点

可用高锰酸钾洗胃的是_mysql 高可用_可用高仿字大全

ES角色划分

接下来看下脑裂出现的情况

解决方案:

在有主节点的系统中,一般都需要考虑脑裂问题,常见的策略无非是:

4.3 数据分片

当数据量过大时,es支持自动拆分,将一个索引的上数据水平拆分到不同的数据块--分片(Shards),为了提供可用性,每个索引在定义时除了分片之外,还会定义副本数量,这里的副本可以理解为数据冗余,其中副本和分片必然不在一个节点上,在主节点异常时,副本可以提供数据查询能力

es默认在创建索引时,分片数为5,每个分片对应一个副本

mysql 高可用_可用高仿字大全_可用高锰酸钾洗胃的是

S分片

ES通过分片,将索引数据水平拆分,分片数越多,每个分片上的数据量就越少;而副本则是对应的每个分片的冗余,可以理解为主备,副本越多,消耗则越大

两点小说明

4.4 数据持久化

最后再说一下es的持久化机制,与前面先说持久化不同,es这里则需要先了解上面的基本流程,索引数据需要保存到主分片上,最终落盘,接下来看一下完整的流程

主分片数据更新流程

mysql 高可用_可用高锰酸钾洗胃的是_可用高仿字大全

ES数据更新流程

简述一下上面的流程

当数据写入到主分片上之后,接下来再看一下这个数据时如何刷新到磁盘上的

分段存储

索引文档以段的形式存储磁盘,即一个索引文件会划分为很多个子文件,这里的子文件就是段

每一个段本身都是一个倒排索引,并且段具有不变性,一旦索引的数据被写入硬盘,就不可再修改;段被写入到磁盘后会生成一个提交点,提交点是一个用来记录所有提交后段信息的文件

段的特性,有下面几个有点

由于段不可变,所以在更新时需要额外处理

延迟写

ES并不会实时将内存中的数据写入段,而是采用延迟写的策略(类似前面的写buffer,然后异步定时刷盘)

es先将内存数据,写入文件缓存系统(操作系统内存),

可用高仿字大全_可用高锰酸钾洗胃的是_mysql 高可用

ES文档写入流程

上图来自 * 两万字教程,带你遨游ElasticSearch

注意几个事项

最后小结一下 es 的持久化

4.5 小结

这一小节主要介绍的是ES的高可用机制,包括ES的集群工作原理,选举策略;采用数据分片支持大数据场景的支持,借助副本来提高可用性;

ES原生支持集群

ES数据持久化策略

参考博文5.一灰灰的总结5.1 综述

本片文章主要是分析当下不同应用场景下的几个主流系统的高可用策略,来看一下如何来保障的系统的高可用

常见的高可用思路redismysqlrabbitmqElasticSearch

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!