MySQL分库分表:MyCAT-问题描述
随着数据库存储的内容越来越多,MySQL主从复制也开始无法存储更多的数据,此时就需要切割表,把一张过大的表切割后分别存储在不同的MySQL中,以便存储更多的内容,承载更多的用户。此阶段出现的典型问题如下:
(1)随着互联网的发展,数据的量级也呈指数级增长,从GB到TB再到PB。对数据的各种操作也愈加困难,传统的关系数据库已经无法满足快速查询与插入数据的需求。如何使单表数据量存储更大?甚至期望单表数据量可以“无限扩大”。
(2)MySQL本身是不支持读写分离的,MySQL只支持主从数据复制,读写功能需要重新开发,。有没有一种办法可以不用一次次重写这部分切面代码?
(3)如何保证集群的中间件不宕机?一旦中间件崩溃,所有的MySQL节点就都无法提供服务了,因为Java代码连接的是MyCAT中间件的地址,对这部分高可用的需求该如何解决?
问题分析与解决方案
针对在8.1节中出现的问题,使用分库分表即可解决。在国内市场上,分库分表与分布式事务通常使用MyCAT来解决。MyCAT是基于阿里巴巴开源的Cobar产品研发的,Cobar的稳定性、可靠性、优秀的架构和性能,以及众多成熟的使用案例使得MyCAT一开始就拥有一个很好的起点。
MyCAT支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等数据库的常见SQL语法,支持读写分离、MySQL主从复制、Galera Cluster集群、XA分布式事务、全局序列号(分布式下的主键生成问题)、数据库分片、密码加密、服务降级、IP地址白名单、SQL黑名单、SQL注入攻击拦截、预编译指令、PostgreSQL的Native协议、存储过程、协调主从切换、Zookeeper序列化、库内分表等相关功能。
MyCAT可以解决分布式事务、读写分离、主从、分片等一系列MySQL集群和分布式问题。MyCAT的操作十分简单,Spring Boot微服务的数据源连接池只操作MyCAT即可。MyCAT会提供给Spring Boot相关地址作为虚拟数据库使用,MyCAT虚拟数据库会通过逻辑的方式操作下属N个MySQL数据库。例如,设置MyCAT分片规则为每500万条数据就换一个数据库进行存储(多库多表的纵向分割),实际上,Spring Boot代码认为自身操作的还是一张表(MyCAT提供的虚拟表)。
在使用MyCAT对数据进行分片处理之后,一个数据库会被切分为多个分片数据库,所有的分片数据库集群构成一个完整的数据库存储。使用MyCAT搭建的一主多从环境架构图如图8-1所示。
图8-1
在搭建完MyCAT架构之后,应用程序(Java、PHP)可通过MyCAT数据中间件地址与账号密码,如同使用正常MySQL一般使用MyCAT,除配置信息外,不需要修改任何代码。MyCAT给应用程序提供的逻辑库与逻辑表,本质上相当于先从应用程序处接收到SQL语句,然后通过各个MySQL主机与主机下的分片进行数据整合,最后将整合后的数据返回给应用程序。
MyCAT提供的表为逻辑表,库为逻辑库,本质上都是不存在的。
MyCAT实战---构建MyCAT一主多从架构
准备三台Linux服务器,其中,将两台服务器作为MySQL,另外一台用来安装MyCAT中间件。
从MyCAT下载地址处下载MyCAT的安装包,如图8-2所示。
图8-2
将下载的MyCAT安装包放入Linux服务器中,并通过tar -zxvf命令进行解压缩,得到mycat文件夹,如图8-3所示。
图8-3
MyCAT的目录结构如表8-1所示。
表8-1
进入MyCAT文件夹的bin目录下,通过命令启动MyCAT脚本。MyCAT的启动命令如下所示:
其他命令如下所示:
如果出现successfully,则说明已启动正常:
MyCAT的关闭命令如下所示:
1. 初次启动MyCAT容易出现的部分错误及解决方式
初次启动MyCAT容易出现的部分错误及解决方式如下。
(1)没有安装JDK。如果出现如下错误提示,则很可能是没有安装JDK:
解决方式:如果已安装JDK,仍然出现上面的错误,则有可能是JDK的相关环境变量不在Linux系统的root账号下所导致的,此时应重新对JDK进行配置。
(2)无法指定Java环境。如果出现如下错误提示,则有可能是MyCAT无法指向JDK的Java程序:
解决方式:打开MyCAT的conf目录下的wrapper.conf文件,并在文件中修改如下代码:
把目录直接指向Java程序,即可解决该问题。
(3)堆栈空间不足。如果出现如下错误提示,则有可能JVM的堆栈空间不足:
解决方式:打开MyCAT的conf目录下的wrapper.conf文件,并在文件中修改或加入如下代码:
增加初始化JVM的堆栈空间,即可解决该问题。
(4)权限不足。如果出现如下错误提示,则有可能是MyCAT在修改某些文件时没有Linux系统的一些权限:
解决方式:使用root赋予其相关权限,或者切换到root账号,即可解决该问题。此外,也有可能是因为wrapper.conf文件没有指向Java可执行文件,此时把wrapper.java.command指向Java_Home的bin目录下的可执行文件即可。
(5)配置文件错误。如果出现如下错误提示,则有可能是MyCAT自身配置文件编写有误:
解决方式:重新编写配置文件,若初次执行启动就遇到该错误,则建议重新下载MyCAT。
(6)主机名错误。如果出现如下错误提示,则有可能是Linux系统的hostName配置出现了异常:
解决方式:
① 修改/etc/sysconfig/network文件,追加如下代码:
② 修改/etc/hosts文件,修改如下代码:
(7)JDK版本问题。如果出现如下错误提示,则有可能是Linux系统的JDK版本出现了异常:
解决方式:在wrapper.conf配置文件中删掉XX:MaxPermSize配置,如图8-4所示。
图8-4
在JDK1.8(或者称JDK8.0)版本之后,取消了永久区,进而使JVM无法识别永久区参数MaxPermSize。
2. MyCAT的基本信息配置
在MyCAT中,与MySQL相关的配置文件主要有三个:
• schema.xml:定义逻辑库、表、分片节点等内容。
• rule.xml:定义分片规则。
• server.xml:定义用户和系统的相关变量,如端口(默认为8066)等。
(1)配置MyCAT的schema.xml。schema.xml中主要记录了主从库等相关信息。本节使用一主两从架构环境,按照7.5节的配置环境填写如下schema信息:
从上面的schema.xml配置文件可以看出,writeHost为写入节点,其内部为写入节点的主从复制读取的readHost节点。
需要注意的是,在schema.xml配置文件中,参数与参数之间要有空格,否则会出现如下错误提示:
通过上述错误提示可以看到,xml文件的第7行第21个字符出现了问题,需要修改dataNode标签中的属性。
schema标签可用来定义MyCAT实例中的逻辑库。MyCAT可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些不同的逻辑库。如果不配置schema标签,则所有的表都属于同一个默认的逻辑库。逻辑库的概念和MySQL的database的概念一样,即在查询两个不同的逻辑库中的表时,需要切换到该逻辑库下进行查询。
schema标签的name属性为Java代码通过MyCAT访问看到的数据库名(逻辑库名)。逻辑库名和后端物理库名可能不同,也可能对应多个后端物理库。
同一个实例下的物理数据库名称不能重复,同理,schema的逻辑库名也不能重复。此处,name属性为自定义的,与实际后端可能不同,访问时以schema标签的name属性为准。
如果在SQL语句中不含limit参数,则默认设置limit参数为sqlMaxLimit属性所对应的数值。如果运行的schema为非拆分库,则sqlMaxLimit属性不会生效,需要自己通过SQL语句加limit。server.xml中的limit是整个MyCAT系统的默认值,此处是当前逻辑库的默认值,默认先看schema.xml的限制数。
schema标签的dataNode属性为逻辑库对应的分片。如果需要配置多个分片,则只需多个dataNode即可:
schema标签的dataNode属性配置为表切分后,还需要配置映射到哪几个数据库中。MyCAT的分片实际上就是库的别名。例如,上面例子配置了两个分片,即dn1和dn2,它们分别对应物理机映射dataHost localhost1的两个库。
另外,其name参数的“dn1”值理应对应dataNode标签。
当schema标签的checkSQLschema属性为true时,MyCAT会修改执行的数据库语句,如下所示:
dataNode标签是实际的物理库配置地址,可以配置多主、主从等其他配置。多个dataHost代表分片对应的物理库地址,下面的writeHost、readHost代表该分片是否配置多写、主从、读写分离等高级特性。
dataNode标签
name参数为自定义的唯一值。在需要分库时,该名称将用来建立表与分片之间的关系。
dataHost参数用来定义该分片属于哪个数据库实例,属性与在datahost标签上定义的name对应。
database参数用来定义该分片属于哪个数据库实例上的具体库。另外,如果没有提前配置<table></table>标签,则MyCAT会找到默认的dataNode,并把表建在默认的dataNode上。如果没有配置默认的dataNode,则MyCAT会报错。
dataHost标签
dataHost标签定义了具体数据库实例,包括读写分离配置与心跳语句。name属性可唯一标示dataHost标签。
maxCon属性指定每个读写实例连接池的最大连接。
minCon属性指定每个读写实例连接池的最小连接,初始化连接池的大小。
balance属性指定读取的负载均衡类型,详情如下所示:
• 0:不开启读写分离机制,把所有读操作都发送到当前可用的writeHost上。
• 1:全部的readHost与stand by writeHost都参与select语句的负载均衡,当为双主双从模式(M1-S1,M2-S2,并且M1 M2互为主备)时,在正常情况下,M2、S1和S2都参与select语句的负载均衡。
• 2:所有读操作都随机地在writeHost和readHost上分发。
• 3:所有读操作都随机地分发在writeHst对应的readHost上执行,writeHost不负担读写压力。
writeType属性指定写入的负载均衡类型,详情如下所示:
• 0:所有的写操作都被发送到配置的第1个writeHost上,如果第1个挂了,则切换到第2个。切换记录在文件dnindex.properties中。
• 1:所有的操作都被随机地发送到配置的writeHost上,不推荐。
dataHost标签的switchType属性可指定写数据库如何进行高可用切换,详情如下所示:
• -1:不自动切换。
• 1:默认值自动切换。
• 2:基于MySQL主从同步的状态决定是否切换,心跳语句为show slavestatus。
• 3:基于mysql galary cluster的切换机制(适合集群)进行切换,心跳语句为show status like 'wsrep%'。
dbType属性指定后端链接的数据库类型目前支持二进制的MySQL协议,还有其他使用JDBC连接的数据库,如MongoDB、Oracle、Spark等。
dbDriver属性指定连接后端数据库使用的driver,目前可选的值有native和JDBC。如果使用native,则因为native执行的是二进制的MySQL协议,所以可以使用MySQL和MariDB,对其他类型的则需要使用JDBC驱动来支持。如果使用JDBC,则需要把符合JDBC4标准的驱动jar包放到mycat\lib目录下 , 检 查 在 jar 包 中 是 否 包 含 目 录 结 构 文 件 METAINF\services\java.sql.Driver并在这个文件中写上具体的driver类名,例如com.mysql.jdbc.Driver。
在dataHost标签内部,readHost标签必须作为writeHost的子标签出现。
readHost需与writeHost配置二进制日志主从复制。
若有其他相关学习需求,可通过GitHub上的MyCAT入门指南进行查看。
(2)登录MyCAT。在配置完schema.xml配置文件之后可以通过./mycatstart后台启动MyCAT。注意,其他MyCAT主机可以通过命令行进入其他所有MySQL服务节点的控制台。
启动成功后,可通过如下命令进入MyCAT控制台管理工具:
上述命令中的“ 192.168.112.140”地址为MyCAT的安装地址,“9066”为MyCAT管理控制台端口。想要进入MyCAT查询工具,则需更改端口号为8066。
账号和密码配置在server.xml中,默认如下所示:
上述<property name="schemas">标签内的属性为该user的可读逻辑库的权限,需要与schema.xml配置文件相对应。
在登录控制台管理工具后,可以输入如下命令查看当前MyCAT内部的逻辑库,结果如图8-5所示。
图8-5
控制台帮助命令如下所示。
部分执行结果如图8-6所示。
图8-6
STATEMENT中的语句可以直接执行,其部分执行结果如图8-7所示。
图8-7
在启动成功之后可以通过如下命令进入MyCAT控制台查询工具,其账号和密码配置在server.xml中:
执行部分查询命令后结果如图8-8所示。
图8-8
此 时 需 要 注 意 的 是 , 如 果 在 schema.xml 中 没 有 配 置 本 机 IP 地 址(127.0.0.1),而是配置了公网IP地址,那么控制台的执行速度将会奇慢无比,而且可能出现连接不到数据源的情况。这属于MyCAT自身的问题。
(3)用Java整合MyCAT。使用Navicat或SQLYog等MySQL图形化界面,或是Java代码,都可以通过MyCAT的端口地址与账号、密码直接进行登录操作。
Java代码使用MyCAT工具进行MySQL操作时,除修改地址、账号、密码、虚拟库、虚拟表等相关配置内容外,和正常使用MySQL无任何区别。通常,MyCAT的虚拟库TESTDB名称可被配置成与MySQL相同的名称,即改为mytest,此时,在Java代码中完全不需要修改业务层面的内容。
构建MyCAT双主多从环境
MySQL双主配置可以保证若其中一台MySQL数据库宕机且无法正常响应,则另一台MySQL的主库节点可以对数据进行写入,保证服务器集群的高可用性。其架构模式优于一主多从架构模式。
1. 双主多从的my.cnf配置
主库1节点的my.cnf配置如下所示:
主库2节点的my.cnf配置如下所示:
slave节点的my.cnf配置如下所示:
对于slave节点,只需修改节点id即可。
2. 双主多从的架构步骤
在更改双主多从的my.cnf配置文件之后,需要重启MySQL,分别将两台从库对应两台主服务器。即从库1复制主库1,从库2复制主库2,此时在从库show slave status\G;命令下的Slave_IO_Running与Slave_SQL_Running两个值都为“YES”的情况下,让主库1复制主库2且主库2复制主库1,便可完成MySQL的双主多从架构。
当通过MyCAT管理双主多从架构时,需要更改MyCAT的schema.xml文件内容,如下所示:
此后通过Java代码对接MyCAT数据库即可。
MyCAT分库——垂直拆分
1. MyCAT垂直拆分方案
一个数据库由很多的表组成,每个表都对应着不同的业务。垂直拆分指按照业务对表进行分类,把不同的表放到不同的数据库上面,使数据库的压力被分担到不同的库上。
在垂直拆分后业务更加清晰,拆分规则明确,系统之间的整合或扩展变得更加容易,但是部分业务表无法连接,跨数据库查询比较烦琐,会出现分布式事务的问题,提高了系统的复杂度,增加了系统性能的损耗,返回速度较慢。
例如,在数据库中包含`product`商品表、`client`客户表、`shopping`购物车表和`company`公司表。假设在商品表中包含1000万件商品和1万个客户,在平均每个客户的购物车里包含30件商品,即在购物车表中共包含30万条信息,所有商品都由800家公司提供。当使用垂直拆分方案时,可以使用两台MySQL,其中一台数据库只包含商品表,而另一台数据库存放客户表、购物车表和公司表。此时数据库压力将会被极大地减轻。
垂直拆分商品表的原因:一是商品数据过多,二是商品被调用的次数也最多,每个客户调用购物车、每个公司查看自己公司产品时都会调用商品表。
虽然购物车表中的数据看起来仍然很多,但是只有MySQL单表承受压力在千万条以上时才会有明显的效率减弱。另外,InnoDB存储引擎的表空间最大容量为64TB,不具体限制单表的大小。在表空间内不仅包含业务数据,还包含索引等相关内容。
在垂直拆分商品表之后,若数据量仍然持续增长,则之后不仅需要进行垂直拆分,还需要用8.3.4中的水平拆分方案对单表进行优化。
2. MyCAT垂直拆分步骤
第1步,更改schema配置文件,如下所示:
MyCAT作为数据库代理,需要逻辑库和逻辑用户,在表切分后需要配置分片。分片需要映射到真实的物理主机上,至于是映射到一台还是映射一台的多个实例上,MyCAT并不关心,只需配置好映射即可。
heartbeat标签代表MyCAT需要对物理库做心跳检测的语句。在正常情况下,生产案例可能配置主从,或者多写或者单库,无论哪种情况,MyCAT都需要维持到数据库的数据源连接,因此需要定时检查后端连接是否正常,心跳语句就是用来检测心跳的。
因为分库时两个库都需要对两个库进行写入操作,所以都被配置为writeHost。
table标签是逻辑表的配置,其中一共包含9个可配置的属性,参数释义如下所示:
(1).name:对应MySQL中的表名。
(2).dataNode:逻辑表所在的分片,该属性值需要和dataNode标签的name属性对应。
(3).rule:逻辑表使用的分片规则名称。规则在conf/rule.xml中配置,该属性值必须与tableRule标签中的name属性值对应。
(4).ruleRequired:是否绑定分片规则,如果为true,就一定要配置rule。
(5).primaryKey:逻辑表对应真实表的主键。
(6).type:逻辑表类型,分为全局表和普通表,后面会详细说明该属性。
(7).autoIncrement:是否启用从自增主键,对应MySQL自增主键,默认是禁用的。
(8).subTable:分表,MyCAT1.6以后开始支持该属性。
(9).needAddLimit:是否允许自动添加在schema标签中设置的limit,默认为true。
第2步,新增两个空白数据库。
分库操作并不是在原来的数据库上进行操作,而是需要删除旧版的数据库,并在dn1、dn2的数据节点分别创建两台数据库,命令如下所示:
第3步,访问MyCAT并进行分库。
在MyCAT命令窗口使用create语句创建表,即可完成分库操作。创建表之后,即可发现shopping表已被写入dn2节点中。在dn1节点中并没有shopping表,也没有表内的相关数据。
注意,创建表语句一定要在MyCAT上创建,而不是在MySQL节点上创建,否则无法起到分库的结果。
MyCAT分表——水平拆分
水平拆分指把同一张表中的数据拆分到不同的数据库中进行存储,或者把一张表拆分成多张小表。与垂直拆分相比,水平拆分不是将表的数据做分类,而是按照某个字段的某种规则把数据分散到多个库中,在每个表中都包含一部分数据。可以将数据的水平拆分理解为按照数据行进行切分,即把表中的某些行拆分到一个数据库中,把另外的某些行拆分到其他数据库中,主要有分表和分库两种模式,该方式提高了系统的稳定性和负载能力,但是跨库连接性能较差。
通常水平拆分可以把shopping表拆分为shopping-2020-01表、shopping-2020-02表,即用日期的方式生成历史数据的shopping表,这样单表数据量就不会像全表那么大,使MySQL的单表效率不影响应用程序的效率。
MyCAT通过rule.xml配置水平分表策略,通过schema.xml(使用table标签)指定表的分表策略。注意:table标签的rule属性需要与rule.xml配置文件对应。
部分常用算法如下所示:
• 枚举分片规则:有些业务需要按照省份或区县保存,而省份、区县是固定的,对这类业务使用本条规则。
• 固定分片哈希算法:类似于十进制的求模运算,区别在于,二进制的操作是取id的二进制低10位,即id二进制&1111111111。如果按照十进制取模运算,则在连续插入1~10时,1~10会被分到1~10个分片,增加了插入事务的控制难度,而此算法根据二进制可能会分到连续的分片,减少插入事务事务控制难度。
• 范围约定算法:需要提前规划好分片字段的某个范围属于哪个分片,例如,当某值大于100且小于1000时,归属为第二分片。
• 取模算法:明确根据id进行十进制求模预算,与固定分片哈希算法相比,在批量插入时可能存在批量插入单事务插入多数据分片,增大了事务一致性难度。
• 按日期分片算法:根据日期进行分片。
• 截取数字做哈希求模范围约束:类似于取模范围约束,此规则支持数据符号字母取模。
• 应用指定算法:此规则是在运行阶段由应用自主决定路由到那个分片。
• 截取数字哈希解析:此规则是截取字符串中的int数值哈希分片。
• 一致性哈希:一致性哈希预算有效解决了分布式数据的扩容问题。需要指定数据库节点数量。
• 按单月小时拆分:此规则是单月内按照小时拆分,最小粒度是小时,一天最多可以有24个分片,最少1个分片。一个月后,下个月从头开始循环。
在每个月月尾都需要手动清理数据。
• 范围求模分片:先进行范围分片计算出分片组,再在组内求模。
• 日期范围哈希分片:思想与范围求模一致,由于日期在取模会有数据
集中问题,所以改成哈希方法。先根据日期分组,再根据时间哈希使得短期内数据分布得更均匀。
• 冷热数据分片:根据日期查询日志数据的冷热数据分布,最近n个月的到实时交易库查询,超过n个月的按照m天分片。
• 自然月分片:按月份列分区,每个自然月一个分片。
下面以日期分片算法为例进行分片,rule.xml的配置如下所示:
schema.xml的配置如下所示:
下面以shopping表为例进行分片,先选择取模算法(mod-long)对两个节点求模,再根据结果分片。rule.xml的配置如下所示:
schema.xml的配置如下所示:
构建HAProxy + MyCAT + MySQL高可用架构
1. HAProxy + MyCAT + MySQL高可用原理
一主多从的MySQL集群有可能出现主服务器宕机,无法正常写入MySQL的情况,所以在实际生产部署时推荐使用双主架构。
双主架构是由MyCAT进行统一管理的。如果MyCAT宕机或者无法正常响应,那么应用程序也无法正常连接到MySQL节点上,所以此时需要对MyCAT进行高可用架构处理。即同时部署N台MyCAT,保证其中M台MyCAT出现异常之后,依旧能够正常提供MyCAT服务。
可以使用HAProxy配合两台MyCAT搭建MyCAT集群,实现高可用性。
HAProxy实现了MyCAT多节点的集群高可用和负载均衡。
如果希望HAProxy+MyCAT+MySQL架构中的HAProxy达到自身的高可用,则可以通过Keepalived+HAProxy来实现,即Keepalived+HAProxy+MyCAT+MySQL架构。由于后面整理了Keepalived+Nginx+Tomcat负载均衡架构,所以此处不再赘述Keepalived。
HAProxy是一个使用C语言编写的自由及开放源代码软件,提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。它支持虚拟主机,是免费、快速并且可靠的一种解决方案,特别适用于那些负载特别大的Web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以简单安全地整合进常规架构中,同时保护Web服务器不被暴露到网络上。包括GitHub、Bitbucket、Stack Overflow、Reddit、Tumblr、Twitter和Tuenti在内的知名网站,及亚马逊网络服务系统均使用了HAProxy。
2. 配置HAProxy
安装HAProxy的步骤如下所示:
第1步,准备好HAProxy安装包,传到/opt目录下。
第2步,解压缩到/usr/local/src目录下,解压缩命令如下所示:
第3步,进入解压缩后的目录,查看内核版本,进行编译:
释义如下所示:
• TARGET =linux310:内核版本,使用uname -r查看内核版本,如
3.10.0-514.el7,此时该参数就为linux310。
• ARCH=x86_64:系统位数。
• PREFIX=/usr/local/haprpxy:/usr/local/haprpxy为HAProxy的安装路径。
第4步,编译完成后,安装HAProxy:
第5步,安装完成后,创建目录、创建HAProxy配置文件:
第6步,修改HAProxy配置文件。在HAProxy配置中有5部分内容,分别如下所示:
• global:设置全局配置参数,属于进程的配置,通常和操作系统相关。
• defaults:配置默认参数,这些参数可以被用在frontend、backend和Listen组件上。
• frontend:接收请求的前端虚拟节点,frontend可以直接指定具体使用后端的backend。
• backend:后端服务集群的配置,是真实服务器,一个backend对应一个或者多个实体服务器。
• Listen:frontend和backend的组合体。
第7步,在haproxy.cfg配置文件中插入以下配置信息,并保存:
3. 验证HAProxy
第1步,启动HAProxy,命令如下所示:
第2步,查看HAProxy进程,采用ps -ef|grep haproxy命令。
第3步,打开浏览器,访问
http://192.168.112.158:7777/admin。
第4步,在弹出框中输入用户名:admin和密码:123123。
第5步,查看HAProxy,查看MyCAT进程,如果界面如图8-9所示,则表示成功。
图8-9
4. HAProxy的常见命令
HAProxy的常用命令如下所示:
5. 高可用总结
高可用有诸多架构可供参考,具体如下。
• Nginx + Tomcat:负载均衡高可用Tomcat架构。该架构只高可用了Tomcat,若部分Tomcat出现异常宕机,则Nginx可以不把任务发送到异常宕机的Tomcat上,从而保证了Tomcat的高可用,但是却没有对Nginx进行高可用处理,即如果Nginx服务器出现异常宕机,则即使多台Tomcat正在良好运行,也无法提供服务。这种架构属于伪高可用架构,即不完全高可用架构。
• Keepalived + Nginx + Tomcat:基于Keepalived的负载均衡高可用
Tomcat架构。后文会对该架构进行详解。
• LVS + Nginx + Tomcat :基于LVS的负载均衡高可用Tomcat架构。与Keepalived+Nginx+Tomcat类似,也可架构成LVS+Keepalived+Nginx+Tomcat的形式,但是通常不建议负载均衡层数过多,因为管理困难。
• HAProxy+MyCAT+MySQL:基于HAProxy与MyCAT的负载均衡高可用MySQL架构。这是当前最流行的MySQL负载均衡高可用架构。
• Keepalived+HAProxy+MySQL:基于HAProxy与Keepalived的负载均衡MySQL架构(该架构容易出现“脑裂”情况,即在高可用架构中,当联系两个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成两个独立的个体。由于相互失去了联系,并且都以为是对方出现了故障,进而争抢“共享资源和“应用服务”,引发严重后果——要么共享资源被瓜分、两边“服务”都起不来了;要么两边“服务”都起来,但同时读写“共享存储”,导致数据损坏。
• Redis+Twemproxy+HAProxy:基于HAProxy与Twemproxy的负载均衡高可用分片Redis架构。
• Netty+HAProxy:基于HAProxy与Nginx的网络通信架构。
负载均衡的本质是使用多台服务器同时运行某一应用程序,达到压力分流的结果。
高可用的本质是在负载均衡环境下,多台服务器同时运行某一应用程序,即便其中一台服务器崩溃或宕机,也不会影响整体服务的提供。
当前的高可用更倾向于使用更高层的中间件部署多台相同的应用程序。
例如,Nginx+Tomcat架构,其负载均衡的N台Tomcat,如果其中M台出现宕机或无法响应的情况,则Nginx仍然可以正常提供Tomcat容器内的应用程序。
通常以TCP或HTTP方式增加中间件的架构时,只需对接中间件节点即可。
例如,Nginx+Tomcat架构可对接Nginx节点,而不需要理会具体的Tomcat地址,因为Nginx会替用户进行转发。如果是Keepalived+Nginx+Tomcat架构,则只对接Keepalived地址即可,不需要理会Nginx与Tomcat的地址。本文使用的 是 HAProxy+MyCAT+MySQL 架 构 , 如 果 使 用 Java 程 序 对 接 , 则 只 需 整 合HAProxy文中配置的地址即可,不需要理会MyCAT与MySQL的地址。Java对接HAProxy的配置如下所示:
无论哪种(LVS、Keepalived、HAProxy和Nginx)HTTP负载均衡中间件,都包含自身的负载均衡算法,具体使用方式可以根据自身应用程序、业务和环境进行配置。例如,读多写少、读少写多、昼夜读取量差别过大、服务器多但单台性能并不好、只有一台服务器性能特别好但其他服务器性能相对一般、只有两台可使用的服务器、业务数据量不同等。
本文给大家讲解的内容是MySQL分库分表:MyCAT
- 下文给大家讲解的是MySQL性能监控解决方案:Prometheus+Grafana