本文转自互联网java
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到个人仓库里查看node
https://github.com/h2pl/Java-Tutorialmysql
喜欢的话麻烦点下Star哈git
文章首发于个人我的博客:github
www.how2playlife.comweb
本文是微信公众号【Java技术江湖】的《从新学习MySQL数据库》其中一篇,本文部份内容来源于网络,为了把本文主题讲得清晰透彻,也整合了不少我认为不错的技术博客内容,引用其中了一些比较好的博客文章,若有侵权,请联系做者。面试
该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减小SQL执行时间,经过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,造成本身的知识框架。算法
若是对本系列文章有什么建议,或者是有什么疑问的话,也能够关注公众号【Java技术江湖】联系做者,欢迎你参与本系列博文的创做和修订。spring
1、MySQL扩展具体的实现方式sql
随着业务规模的不断扩大,须要选择合适的方案去应对数据规模的增加,以应对逐渐增加的访问压力和数据量。
关于数据库的扩展主要包括:业务拆分、主从复制、读写分离、数据库分库与分表等。这篇文章主要讲述数据库分库与分表
(1)业务拆分
在 大型网站应用之海量数据和高并发解决方案总结一二 一篇文章中也具体讲述了为何要对业务进行拆分。
业务起步初始,为了加快应用上线和快速迭代,不少应用都采用集中式的架构。随着业务系统的扩大,系统变得愈来愈复杂,愈来愈难以维护,开发效率变得愈来愈低,而且对资源的消耗也变得愈来愈大,经过硬件提升系统性能的方式带来的成本也愈来愈高。
所以,在选型初期,一个优良的架构设计是后期系统进行扩展的重要保障。
例如:电商平台,包含了用户、商品、评价、订单等几大模块,最简单的作法就是在一个数据库中分别建立users、shops、comment、order四张表。
可是,随着业务规模的增大,访问量的增大,咱们不得不对业务进行拆分。每个模块都使用单独的数据库来进行存储,不一样的业务访问不一样的数据库,将本来对一个数据库的依赖拆分为对4个数据库的依赖,这样的话就变成了4个数据库同时承担压力,系统的吞吐量天然就提升了。
(2)主从复制
通常是主写从读,一主多从
一、MySQL5.6 数据库主从(Master/Slave)同步安装与配置详解
二、MySQL主从复制的常见拓扑、原理分析以及如何提升主从复制的效率总结
三、使用mysqlreplicate命令快速搭建 Mysql 主从复制
上述三篇文章中,讲述了如何配置主从数据库,以及如何实现数据库的读写分离,这里再也不赘述,有须要的选择性点击查看。
上图是网上的一张关于MySQL的Master和Slave之间数据同步的过程图。
主要讲述了MySQL主从复制的原理:数据复制的实际就是Slave从Master获取Binary log文件,而后再本地镜像的执行日志中记录的操做。因为主从复制的过程是异步的,所以Slave和Master之间的数据有可能存在延迟的现象,此时只能保证数据最终的一致性。
(3)数据库分库与分表
咱们知道每台机器不管配置多么好它都有自身的物理上限,因此当咱们应用已经能触及或远远超出单台机器的某个上限的时候,咱们唯有寻找别的机器的帮助或者继续升级的咱们的硬件,但常见的方案仍是经过添加更多的机器来共同承担压力。
咱们还得考虑当咱们的业务逻辑不断增加,咱们的机器能不能经过线性增加就能知足需求?所以,使用数据库的分库分表,可以立竿见影的提高系统的性能,关于为何要使用数据库的分库分表的其余缘由这里再也不赘述,主要讲具体的实现策略。请看下边章节。
关键字:用户ID、表容量
对于大部分数据库的设计和业务的操做基本都与用户的ID相关,所以使用用户ID是最经常使用的分库的路由策略。用户的ID能够做为贯穿整个系统用的重要字段。所以,使用用户的ID咱们不只能够方便咱们的查询,还能够将数据平均的分配到不一样的数据库中。(固然,还能够根据类别等进行分表操做,分表的路由策略还有不少方式)
接着上述电商平台假设,订单表order存放用户的订单数据,sql脚本以下(只是为了演示,省略部分细节):
CREATE TABLE `order` (
`order_id` bigint(32) primary key auto_increment,
`user_id` bigint(32),
...
) 复制代码
当数据比较大的时候,对数据进行分表操做,首先要肯定须要将数据平均分配到多少张表中,也就是:表容量。
这里假设有100张表进行存储,则咱们在进行存储数据的时候,首先对用户ID进行取模操做,根据 user_id%100
获取对应的表进行存储查询操做,示意图以下:
例如,user_id = 101
那么,咱们在获取值的时候的操做,能够经过下边的sql语句:
select * from order_1 where user_id= 101复制代码
其中,order_1
是根据 101%100
计算所得,表示分表以后的第一章order表。
注意:
在实际的开发中,若是你使用MyBatis作持久层的话,MyBatis已经提供了很好得支持数据库分表的功能,例如上述sql用MyBatis实现的话应该是:
接口定义:
/**
* 获取用户相关的订单详细信息
* @param tableNum 具体某一个表的编号
* @param userId 用户ID
* @return 订单列表
*/
public List<Order> getOrder(@Param("tableNum") int tableNum,@Param("userId") int userId);复制代码
xml配置映射文件:
<select id="getOrder" resultMap="BaseResultMap">
select * from order_${tableNum}
where user_id = #{userId}
</select>复制代码
其中${tableNum}
含义是直接让参数加入到sql中,这是MyBatis支持的特性。
注意:
另外,在实际的开发中,咱们的用户ID更多的多是经过UUID生成的,这样的话,咱们能够首先将UUID进行hash获取到整数值,而后在进行取模操做。复制代码
数据库分表可以解决单表数据量很大的时候数据查询的效率问题,可是没法给数据库的并发操做带来效率上的提升,由于分表的实质仍是在一个数据库上进行的操做,很容易受数据库IO性能的限制。
所以,如何将数据库IO性能的问题平均分配出来,很显然将数据进行分库操做能够很好地解决单台数据库的性能问题。
分库策略与分表策略的实现很类似,最简单的都是能够经过取模的方式进行路由。
仍是上例,将用户ID进行取模操做,这样的话获取到具体的某一个数据库,一样关键字有:
用户ID、库容量
路由的示意图以下:
上图中库容量为100。
一样,若是用户ID为UUID请先hash而后在进行取模。
上述的配置中,数据库分表能够解决单表海量数据的查询性能问题,分库能够解决单台数据库的并发访问压力问题。
有时候,咱们须要同时考虑这两个问题,所以,咱们既须要对单表进行分表操做,还须要进行分库操做,以便同时扩展系统的并发处理能力和提高单表的查询性能,就是咱们使用到的分库分表。
分库分表的策略相对于前边两种复杂一些,一种常见的路由策略以下:
1、中间变量 = user_id%(库数量*每一个库的表数量);
2、库序号 = 取整(中间变量/每一个库的表数量);
3、表序号 = 中间变量%每一个库的表数量;复制代码
例如:数据库有256 个,每个库中有1024个数据表,用户的user_id=262145,按照上述的路由策略,可得:
1、中间变量 = 262145%(256*1024)= 1;
2、库序号 = 取整(1/1024)= 0;
3、表序号 = 1%1024 = 1;复制代码
这样的话,对于user_id=262145,将被路由到第0个数据库的第1个表中。
示意图以下:
关于分库分表策略的选择有不少种,上文中根据用户ID应该是比较简单的一种。其余方式好比使用号段进行分区或者直接使用hash进行路由等。有兴趣的能够自行查找学习。
关于上文中提到的,若是用户的ID是经过UUID的方式生成的话,咱们须要单独的进行一次hash操做,而后在进行取模操做等,其实hash自己就是一种分库分表的策略,使用hash进行路由策略的时候,咱们须要知道的是,也就是hash路由策略的优缺点,优势是:数据分布均匀;缺点是:数据迁移的时候麻烦,不能按照机器性能分摊数据。
上述的分库和分表操做,查询性能和并发能力都获得了提升,可是还有一些须要注意的就是,例如:本来跨表的事物变成了分布式事物;因为记录被切分到不一样的数据库和不一样的数据表中,难以进行多表关联查询,而且不能不指定路由字段对数据进行查询。分库分表以后,若是咱们须要对系统进行进一步的扩阵容(路由策略变动),将变得很是不方便,须要咱们从新进行数据迁移。
最后须要指出的是,分库分表目前有不少的中间件可供选择,最多见的是使用淘宝的中间件Cobar。
GitHub地址:github.com/alibaba/cob…
文档地址为:github.com/alibaba/cob…
关于淘宝的中间件Cobar本篇内容不具体介绍,会在后边的学习中在作介绍。
另外Spring也能够实现数据库的读写分离操做,后边的文章,会进一步学习。
上述中,咱们学到了如何进行数据库的读写分离和分库分表,那么,是否是能够实现一个可扩展、高性能、高并发的网站那?很显然还不能够!一个大型的网站使用到的技术远不止这些,能够说,这些都是其中的最基础的一个环节,由于还有不少具体的细节咱们没有掌握到,好比:数据库的集群控制,集群的负载均衡,灾难恢复,故障自动切换,事务管理等等技术。所以,还有不少须要去学习去研究的地方。
总之:
路漫漫其修远兮,吾将上下而求索。复制代码
前方道路美好而光明,2017年新征程,不泄步!
一个完全开源的,面向企业应用开发的大数据库集群
支持事务、ACID、能够替代MySQL的增强版数据库
一个能够视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品
以上内容来自Mycat官网,简单来讲,Mycat就是一个数据库中间件,对于咱们开发来讲,就像是一个代理,当咱们须要使用到多个数据库和须要进行分库分表的时候,咱们只须要在mycat里面配置好相关规则,程序无需作任何修改,只是须要将本来的数据源连接到mycat而已,固然若是之前有多个数据源,须要将数据源切换为单个数据源,这样有个好处就是当咱们的数据量已经很大的时候,须要开始分库分表或者作读写分离的时候,不用修改代码(只须要改一下数据源的连接地址)
使用Mycat分表分库实践
haha,首先这不是一篇入门Mycat的博客但小编感受又很入门的博客!这篇博客主要讲解Mycat中数据分片的相关知识,同时小编将会在本机数据库上进行测试验证,图文并茂展现出来。
数据库分区分表,咋一听很是地高大上,总有一种高高在上,可望不可即的感受,但小编想说的是,其实,做为一个开发人员,该来的老是会来,该学的东西你仍是得学,区别只是时间前后顺序的问题。
分区就是把一个数据表的文件和索引分散存储在不一样的物理文件中。
mysql支持的分区类型包括Range、List、Hash、Key,其中Range比较经常使用:
RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。
LIST分区:相似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数能够包含MySQL 中有效的、产生非负整数值的任何表达式。
KEY分区:相似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
分表是指在逻辑上将一个表拆分红多个逻辑表,在总体上看是一张表,分表有水平拆分和垂直拆分两种,举个例子,将一张大的存储商户信息的表按照商户号的范围进行分表,将不一样范围的记录分布到不一样的表中。
Mycat 的分片其实和分表差很少意思,就是当数据库过于庞大,尤为是写入过于频繁且很难由一台主机支撑是,这时数据库就会面临瓶颈。咱们将存放在同一个数据库实例中的数据分散存放到多个数据库实例(主机)上,进行多台设备存取以提升性能,在切分数据的同时能够提升系统的总体性。
数据分片是指将数据全局地划分为相关的逻辑片断,有水平切分、垂直切分、混合切分三种类型,下面主要讲下Mycat的水平和垂直切分。有一点很重要,那就是Mycat是分布式的,所以分出来的数据片分布到不一样的物理机上是正常的,靠网络通讯进行协做。
水平切分
就是按照某个字段的某种规则分散到多个节点库中,每一个节点中包含一部分数据。能够将数据水平切分简单理解为按照数据行进行切分,就是将表中的某些行切分到一个节点,将另外某些行切分到其余节点,从分布式的总体来看它们是一个总体的表。
垂直切分
一个数据库由不少表构成,每一个表对应不一样的业务,垂直切分是指按照业务将表进行分类并分不到不一样的节点上。垂直拆分简单明了,拆分规则明确,应用程序模块清晰、明确、容易整合,可是某个表的数据量达到必定程度后扩展起来比较困难。
混合切分
为水平切分和垂直切分的结合。
上面说到,垂直切分主要是根据具体业务来进行拆分的,那么,咱们能够想象这么一个场景,假设咱们有一个很是大的电商系统,那么咱们须要将订单表、流水表、用户表、用户评论表等分别分不到不一样的数据库中来提升吞吐量,架构图大概以下:
因为小编是在一台机器上测试,所以就只有host1这个节点,但不一样的表仍是依旧对应不一样的数据库,只不过是全部数据库属于同一个数据库实例(主机)而已,后期不一样主机只需增长
节点便可。
mycat配置文件以下:
server.xml
<user name="root">
<property name="password">root</property>
// 对应四个逻辑库
<property name="schemas">order,trade,user,comment</property>
</user>
复制代码
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 4个逻辑库,对应4个不一样的分片节点 -->
<schema name="order" checkSQLschema="false" sqlMaxLimit="100" dataNode="database1" />
<schema name="trade" checkSQLschema="false" sqlMaxLimit="100" dataNode="database2" />
<schema name="user" checkSQLschema="false" sqlMaxLimit="100" dataNode="database3" />
<schema name="comment" checkSQLschema="false" sqlMaxLimit="100" dataNode="database4" />
<!-- 四个分片,对应四个不一样的数据库 -->
<dataNode name="database1" dataHost="localhost1" database="database1" />
<dataNode name="database2" dataHost="localhost1" database="database2" />
<dataNode name="database3" dataHost="localhost1" database="database3" />
<dataNode name="database4" dataHost="localhost1" database="database4" />
<!-- 实际物理主机,只有这一台 -->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="localhost:3306" user="root"
password="root">
</writeHost>
</dataHost>
</mycat:schema>
复制代码
登录本机mysql,建立order,trade,user,comment
4个数据库:
create database database1 character set utf8;
create database database2 character set utf8;
create database database3 character set utf8;
create database database4 character set utf8;
复制代码
执行bin
目录下的startup_nowrap.bat
文件,若是输出下面内容,则说明已经启动mycat成功,若是没有,请检查order,trade,user,comment
4个数据库是否已经建立。
采用下面语句登录Mycat服务器:
mysql -uroot -proot -P8066 -h127.0.0.1
在comment
数据库中建立Comment
表,并插入一条数据
上图1处新建一个Comment
表,2处插入一条记录,3处查看记录插入到哪一个数据节点中,即database4
。
server.xml
<user name="root">
<property name="password">root</property>
<property name="schemas">TESTDB</property>
</user>
复制代码
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="root">
</writeHost>
</dataHost>
</mycat:schema>
复制代码
rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
rang-long
</rule>
</tableRule>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
</mycat:rule>
复制代码
conf
目录下的autopartition-long.txt
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
复制代码
上面的配置建立了一个名为TESTDB
的逻辑库,并指定了须要切分的表
travelrecord
,分区的策略采用
rang-long
算法,即根据
id
数据列值的范围进行切分,具体的规则在
autopartition-long.txt
文件中定义,即
id
在
0-500*10000
范围内的记录存放在
db1
的
travelrecord
表中,
id
在
500*10000 - 1000*10000
范围内的记录存放在
db2
数据库的
travelrecord
表中,下面咱们插入两条数据,验证是否和分片规则一致。
建立db1,db2,db3
数据库
create database db1 character set utf8;
create database db2 character set utf8;
create database db3 character set utf8;
复制代码
确实是这样的,到此咱们就完成了mycat数据库的水平切分,这个例子只是演示按照id列值得范围进行切分,mycat还支持不少的分片算法,如取模、一致性哈希算法、按日期分片算法等等,你们能够看《分布式数据库架构及企业实战----基于Mycat中间件》这本书深刻学习。
至于为何须要读写分离,在我以前的文章有介绍过了,相信看到这篇文章的人也知道为何须要读写分离了,固然若是你也须要了解一下,那么欢迎查看我以前的文章SpringBoot Mybatis 读写分离配置,顺便也能够了解一下怎么经过代码进行读写分离的
主从复制是读写分离的关键,无论经过什么方式进行读写分离,前提就是MySQL有主从复制,当前双机主从也行,可是关键的关键,是要能保证2个库的数据能一致(出掉刚写入主库从库还未能及时反应过来的状况),若是2个库的数据不一致,那么读写分离也有没有任何意义了,具体MySQL怎么作主从复制能够查看我以前的文章MySQL主从复制搭建,基于日志(binlog)
Mycat的用户就跟MySQL用户是同一个意思,主要配置连接到Mycat的用户名以及密码,以及能使用的逻辑库,用户信息主要在server.xml中配置的,具体以下
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="defaultSqlParser">druidparser</property>
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="mutiNodeLimitType">1</property> 0:开启小数量级(默认) ;1:开启亿级数据排序
<property name="mutiNodePatchSize">100</property> 亿级数量排序批量
<property name="processors">32</property> <property name="processorExecutor">32</property>
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
</system>
<user name="raye">
<property name="password">rayewang</property>
<property name="schemas">separate</property>
</user>
</host>
</mycat:server>
复制代码
其中
定义了一个名为raye的用户,标签user中的
定义了用户的密码,
定义了用户可使用的逻辑库
Mycat的配置有不少,不过由于咱们只是使用Mycat的读写分类的功能,因此用到的配置并很少,只须要配置一些基本的,固然本文也只是会介绍到读写分离相关的配置,其余配置建议读者本身查看一下文档,或者经过其余方式了解,逻辑库是在schema.xml
中配置的
首先介绍Mycat逻辑库中的一些配置标签
schema
标签是用来定义逻辑库的,schema
有四个属性dataNode
,checkSQLschema
,sqlMaxLimit
,name
dataNode
标签属性用于绑定逻辑库到某个具体的 database 上,1.3 版本若是配置了 dataNode,则不能够配置分片表,1.4 能够配置默认分片,只须要配置须要分片的表便可
name
是定义当前逻辑库的名字的,方便server.xml
中定义用户时的引用
checkSQLschema
当该值设置为 true 时,若是咱们执行语句select from separate.users;则 MyCat 会把语句修改 为select from users;。即把表示 schema 的字符去掉,避免发送到后端数据库执行时报(ERROR 1146 (42S02): Table ‘separate.users’ doesn’t exist)。 不过,即便设置该值为 true ,若是语句所带的是并不是是 schema 指定的名字,例如:select * from db1.users; 那么 MyCat 并不会删除 db1 这个字段,若是没有定义该库的话则会报错,因此在提供 SQL语句的最好是不带这个字段。
sqlMaxLimit
当该值设置为某个数值时。每条执行的 SQL 语句,若是没有加上 limit 语句,MyCat 也会自动的加上所对应的值。例如设置值为 100,执行select from users;的效果为和执行select from users limit 100;相同。设置该值的话,MyCat 默认会把查询到的信息所有都展现出来,形成过多的输出。因此,在正常使用中,仍是建议加上一个值,用于减小过多的数据返回。固然 SQL 语句中也显式的指定 limit 的大小,不受该属性的约束。须要注意的是,若是运行的 schema 为非拆分库的,那么该属性不会生效。须要手动添加 limit 语句。
schema
标签中有标签table
用于定义不一样的表分片信息,不过咱们只是作读写分离,并不会用到,因此这里就很少介绍了
dataNode
dataNode 标签订义了 MyCat 中的数据节点,也就是咱们一般说所的数据分片。一个 dataNode 标签就是一个独立的数据分片,dataNode
有3个属性:name
,dataHost
,database
。
name
定义数据节点的名字,这个名字须要是惟一的,此名字是用于table
标签和schema
标签中引用的
dataHost
该属性用于定义该分片属于哪一个数据库实例的,属性值是引用 dataHost 标签上定义的 name 属性
database
该属性用于定义该分片属性哪一个具体数据库实例上的具体库,由于这里使用两个纬度来定义分片,就是:实例+具体的库。由于每一个库上创建的表和表结构是同样的。因此这样作就能够轻松的对表进行水平拆分
dataHost
是定义真实的数据库链接的标签,该标签在 mycat 逻辑库中也是做为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句,dataHost
有7个属性:name
,maxCon
,minCon
,balance
,writeType
,dbType
,dbDriver
,有2个标签heartbeat
,writeHost
,其中writeHost
标签中又包含一个readHost
标签
name
惟一标识 dataHost 标签,供dataNode
标签使用
maxCon
指定每一个读写实例链接池的最大链接。也就是说,标签内嵌套的 writeHost、readHost 标签都会使用这个属性的值来实例化出链接池的最大链接数
minCon
指定每一个读写实例链接池的最小链接,初始化链接池的大小
balance
读取负载均衡类型
writeType
写入负载均衡类型,目前的取值有 3 种:
dbType
指定后端链接的数据库类型,目前支持二进制的 mysql 协议,还有其余使用 JDBC 链接的数据库。例如:mongodb、oracle、spark 等
dbDriver
指定链接后端数据库使用的 Driver,目前可选的值有 native 和 JDBC。使用 native 的话,由于这个值执行的 是二进制的 mysql 协议,因此可使用 mysql 和 maridb。其余类型的数据库则须要使用 JDBC 驱动来支持。从 1.6 版本开始支持 postgresql 的 native 原始协议。 若是使用 JDBC 的话须要将符合 JDBC 4 标准的驱动 JAR 包放到 MYCATlib 目录下,并检查驱动 JAR 包中包括以下目录结构的文件:META-INFservicesjava.sql.Driver。在这个文件内写上具体的 Driver 类名,例如: com.mysql.jdbc.Driver。
heartbeat
这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL 可使用 select user(),Oracle 可使用 select 1 from dual 等。 这个标签还有一个 connectionInitSql 属性,主要是当使用 Oracla 数据库时,须要执行的初始化 SQL 语句就这个放到这里面来。例如:alter session set nlsdateformat='yyyy-mm-dd hh24:mi:ss'
writeHost
,readHost
这两个标签都指定后端数据库的相关配置给 mycat,用于实例化后端链接池。惟一不一样的是,writeHost 指定写实例、readHost 指定读实例,组着这些读写实例来知足系统的要求。 在一个 dataHost 内能够定义多个 writeHost 和 readHost。可是,若是 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的全部 readHost 都将不可用。另外一方面,因为这个 writeHost 宕机系统会自动的检测到,并切换到备用的 writeHost 上去,这2个标签属性都一致,拥有host
,url
,password
,user
,weight
,usingDecrypt
等属性
host
用于标识不一样实例,通常 writeHost 咱们使用M1,readHost 咱们用S1
url
真实数据库的实例的连接地址,若是是使用 native 的 dbDriver,则通常为 address:port 这种形式。用 JDBC 或其余的dbDriver,则须要特殊指定。当使用 JDBC 时则能够这么写:jdbc:mysql://localhost:3306/
user
真实数据库实例的连接用户名
password
真实数据库实例的连接密码
weight
权重 配置在 readhost 中做为读节点的权重,主要用于多台读取的数据库实例机器配置不一样的状况,能够根据权重调整访问量
usingDecrypt
是否对密码加密默认 0 否 如须要开启配置 1,同时使用加密程序对密码加密
注意,readHost是在writeHost标签内的,不是单独的
如下是个人读写分离配置文件
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="separate" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"/>
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.1.126:3307" user="root"
password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS2" url="192.168.1.126:3308" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
复制代码
前面已经差很少都解释清楚了,由于我只是用的基本的主从复制,因此个人将dataHost
的balance
设置成了3
启动mycat,而后用数据库链接工具链接到mycat,能够测试是否配置成功,最简单的就是经过修改从库的数据,这样方便查看究竟是运行到哪一个库上面了,另外因为我是基于docker启动的mycat,因此若是是直接在系统中运行的mycat的,能够去看官方文档,看看到底怎么启动mycat