随着计算机和信息技术的迅猛发展,行业应用系统的规模迅速扩大,行业应用所产生的数据量呈爆炸式增加,动辄达到数百TB甚至数百PB的规模,已远远超出传统计算技术和信息系统的处理能力,集中式数据库面对大规模数据处理逐渐表现出其局限性。所以,人们但愿寻找一种能快速处理数据和及时响应用户访问的方法,也但愿对数据进行集中分析、管理和维护。这已经成为迫切需求。前端
分布式数据库是在集中式数据库的基础上发展起来的,是计算机技术和网络技术结合的产物。分布式数据库是指数据在物理上分布而在逻辑上集中管理的数据库系统。物理上分布是指数据分布在物理位置不一样并由网络链接的节点或站点上;逻辑上集中是指各数据库节点之间的逻辑上是一个总体,并由统一的数据库管理系统管理。不一样的节点分布能够跨不一样的机房、城市甚至国家。java
分布式数据库具备透明性、数据冗余性、易于扩展性、自治性等特色,还具备经济、性能优越、响应速度更快、灵活的体系结构、易于集成现有系统等特色。node
分布式数据库尽管有着天生的高贵血统,但它依赖调整网络,对事务的处理远没有传统数据库成熟,在很长一段时间内分布式数据存储将与传统数据存储共存。mysql
MyCat是一个完全开源的面向企业应用开发的大数据库集群,支持事务、ACID,是能够替代MySQL的增强版数据库。MyCat被视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群,它是整合了内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server,是结合了传统数据库和新型分布式数据仓库的新一代企业级数据库产品,也是一个优秀的数据库中间件。git
MyCat是经过Cobar改良而生。MyCat支持Oracle、PostgreSQL,从1.3版本开始支持NoSQL(SequoiaDB及MongoDB)并引入了Druid解析器。2016年MyCat发布了1.5版本,2018年发布了 1.6.6版本 。目前MyCat2.0项目已经启动,核心代码已经提交(github.com/MyCatApache…github
一般在实际应用中,业务开发人员并不须要知道中间件的存在,只须要关注数据库,因此数据库中间件能够被看成一个或多个数据库集群构成的逻辑库。sql
既然有逻辑库,就会有逻辑表。在分布式数据库中,对于应用来讲,读写数据的表就是逻辑表。逻辑表能够分布在一个或多个分片库中,也能够不分片。数据库
1)分片表后端
分片表是指将数据量很大的表切分到多个数据库实例中,全部分片组合起来构成了一张完整的表。例如在MyCat上配置t_node的分片表,数据按照规则被切分到dn一、dn2两个节点。缓存
<table name=”t_node” primaryKey=”vid” autoIncrement=”true” dataNode=”nd1,dn2” rule=”rule1” />
复制代码
2)非分片表
并不是全部的表在数量很大时都须要进行分片。非分片表是相对分片表而言的,不须要进行数据切分的表。以下面配置中的t_node只存在于节点dn1上。
<table name=”t_node” primaryKey=”vid” autoIncrement=”true” dataNode=”dn1” />
复制代码
3)ER表
关系型数据库是基于实体关系模型(Entity Relationship Model)的,MyCat中的ER表便来源于此。基于此思想,MyCat提出了基于E-R关系的数据分片策略,子表的记录与其所关联的父表的记录存放在同一个数据分片上,即子表依赖于父表,经过表分组(Table Group)保证数据关联查询不会跨库操做。
表分组是解决跨分片数据关联查询的一种很好的思路,也是数据切分的一条重要规则。
4)全局表
在一个真实的业务场景中每每存在大量相似的字典表,这些字典表中的数据变更不频繁,并且数据规模不大,不多有超过数十万条的记录。
当业务表由于规模进行分片后,业务表与这些附属的字典表之间的关联查询就成了比较棘手的问题,因此在MyCat中经过数据冗余来解决这类表的关联查询,即全部分片都复制了一份数据,咱们把这些冗余数据的表定义为全局表。
数据冗余是解决跨分片数据关联查询的一种很好的思路,也是数据切分规划的另外一条重要规则。
将数据切分后,一个大表被分到不一样的分片数据库上,每一个表分片所在的数据库是分片节点。
将数据切分后,每一个分片节点不必定会独占一台机器,同一台机器上能够有多个分片数据库,这样一个或多个分片节点所在的机器就是节点主机。为了规避单节点主机并发数量的限制,尽可能将读写压力高的分片节点均匀地放在不一样的节点主机上。
MyCat原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句作了一些特定的分析,例如分片分析、路由分析、读写分离分析、缓存分析等,而后将此SQL语句发日后端的真实数据库,并将返回的结果作适当的处理,最终再返回给用户。
MyCat收到一条SQL语句时,首先解析SQL语句涉及的表,接着查看此表的定义,若是该表存在分片规则,则获取SQL语句里分片字段的值,并匹配分片函数,获得该SQL语句对应的分片列表,而后将SQL语句发送到相应的分片去执行,最后处理全部分片返回的数据并返回给客户端。
schema.xml是MyCat的重要配置文件,它管理着逻辑库、分片表、分片节点和分片主机等信息。
service.xml是系统参数的配置文件,掌握MyCat优化方法,必需熟悉该文件的配置项。
sequence是全局序列的配置文件。
server.xml配置文件包含了MyCat的系统配置信息,对应的源码是SystemConfig.java。它有两个重要的标签,分别是user、system。掌握system标签的各项配置属性是MyCat调优的关键。
<MyCat:server xmlns:MyCat="http://io.MyCat/">
<system>
<property name="nonePasswordLogin">0</property> <!-- 0为须要密码登录、1为不须要密码登录 ,默认为0,设置为1则须要指定默认帐户-->
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sequnceHandlerType">2</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的状况下,检查关联字段中是否有分片字段 .默认 false -->
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
<property name="processorBufferPoolType">0</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="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> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(若是分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,可是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">1</property>
<!--
单位为m
-->
<property name="memoryPageSize">64k</property>
<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">false</property>
<!-- XA Recovery Log日志路径 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->
<!-- XA Recovery Log日志名称 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
<!--若是为 true的话 严格遵照隔离级别,不会在仅仅只有select语句的时候在事务中切换链接-->
<property name="strictTxIsolation">false</property>
<property name="useZKSwitch">true</property>
</system>
<!-- 全局SQL防火墙设置 -->
<!--白名单可使用通配符%或着*-->
<!--例如<host host="127.0.0.*" user="root"/>-->
<!--例如<host host="127.0.*" user="root"/>-->
<!--例如<host host="127.*" user="root"/>-->
<!--例如<host host="1*7.*" user="root"/>-->
<!--这些配置状况下对于127.0.0.1都能以root帐户登陆-->
<!--
<firewall>
<whitehost>
<host host="1*7.0.0.*" user="root"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
</MyCat:server>
复制代码
schema.xml 做为MyCat中重要的配置文件之一,涵盖了MyCat的逻辑库、表、分片规则、分片节点及数据源。
1)schema 标签
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
复制代码
schema标签用于定义MyCat实例中的逻辑库。MyCat能够有多个逻辑库,每一个逻辑库都有本身的相关配置。可使用schema标签来划分不一样的逻辑库,若是有配置schema标签,则全部的表配置都会属于同一个默认的逻辑库。
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
<schema name="USERDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="company" dataNode="dn10,dn11,dn12" rule="auto-sharding-long" />
</schema>
复制代码
如上所示配置了两个不一样的逻辑库,逻辑库的概念等同于MySQL数据库中的Database概念,咱们在查询逻辑库中的表时,须要切换到该逻辑库下才能够查询其中的表。
checkSQLschema属性,当把该值设置为true时,若是咱们执行语句 select * from TESTDB.travelrecord;,则MyCat会把schema字符去掉,把SQL语句修改成select * from travelrecord;可避免发送到后端数据库执行时报错。
SqlMaxLimit属性,当该属性设置为某个值时,每次执行的SQL语句若是没有加上limit语句,MyCat也会自动在limit语句后加上对应的值。若是不设置该值,则MyCat会把查询到的信息所有返回。
2)table 标签
<table name=”travelrecord” dataNode=”dn1,dn2,dn3” rule=”auto-sharding-long”></table>
复制代码
table标签订义了MyCat中的逻辑表,全部须要拆分的的表都须要在table标签中定义。
table标签的主要属性见下表,具体介绍参见MyCat官方网站 www.MyCat.io 。
属性名 | 值 | 数量限制 |
---|---|---|
name | String | 1 |
dataNode | String | 1..* |
rule | String | 0..1 |
ruleRequired | boolean | 0..1 |
primaryKey | String | 1 |
type | String | 0..1 |
autoIncrement | boolean | 0..1 |
subTables | String | 1 |
needAddLimit | Boolean | 0..1 |
3)childTable 标签
childTable标签用于定义 E-R 分片的子表,经过标签上的属性与父表进行关联。
4)dataNode标签
dataNode标签订义了MyCat中的数据节点,也就是咱们一般所说的数据分片。一个dataNode标签就是一个独立的数据分片。
5)dataHost标签
dataHost标签在MyCat逻辑库中做为底层标签存在,直接定义了具体的数据库实例,读写分离和心跳语句。
Heartbeat标签用来配置心跳检查语句,Mysql可使用select user(),Oracle可使用select 1 from dual 等。
writeHost和readHost是读写的配置,一个dataHost内能够配置多个读和写。但若是writeHost指定的后端数据库宕机,那么这个writeHost绑定的全部readHost也将不可用;另外一方面,MyCat会自动检测到writeHost宕机,并切换到备用的writeHost上。
在MyCat中将表分为两种大的概念:数据量小且不须要作数据切分的表,称为非分片表;数据量大到单库性能、容量不足以支撑,数据须要经过水平切分均匀分布到不一样的数据库中的表,称为分片表。而中间件最终须要处理的事情是对数据切分、聚合。
ER模型是实体关系模型,普遍采用概念模型设计方法,基本元素是实体、关系和属性。MyCat将它引入数据切分规则中,使得有互相依赖的表可以按照某一规则切分到相同的节点上,避免跨库Join关联查询。具体详情配置内容在这里不作描述请参考官方文档。
delete操做不支持没有主键的表。没有主键的表在不一样节点的顺序不一样,若是执行 select ...limit...,则将出现不一样的结果集。
不支持XA事务,在提交上可能回滚。
因为集群是乐观的并发控件,事务commit可能在该阶段停止,因此若是有两个事务向集群中的不一样节点的同一行写入并提交,则失败的节点将停止。对于集群级别的停止,集群返回死锁错误。
整个集群的写入吞吐量由最弱的节点限制,若是有一个节点变得缓慢,那么整个集群将变得缓慢。
集群内部按照id自增加机制写入数据,好比集群中有三台多是3,6,9这样的递增。
MyCat是一个中间件的第三方应用,sharding-jdbc是一个jar包。 由于MyCat是单独部署,因此使用MyCat就像是访问数据库同样,而sharding-jdbc的逻辑都是须要在工程里写的。
若是只是单独应用可使用轻量级的Sharding-JDBC,若是多个服务都须要操做数据库则使用MyCat更合适。由于用Sharding-JDBC须要在每个工程里边都配置上相应的分片等逻辑,而MyCat只须要配置一份单独部署。
做者:高玉珑
来源:宜信技术学院