介绍
MyCAT是数据库中间件。
能用于读写分离、数据分片、多数据源整合。
MyCAT的原理就是拦截,对SQL语句进行拦截,做一些特定的分析,之后将SQL发送到真实的数据库,并将结果处理返回给用户。
配置
配置mycat的文档非常详细,xml中解释的也非常完美。在此记录几个较为常用的配置。
server.xml中配置用户登录:
<user name="user">
<property name="password">user</property> <!-- 密码 -->
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property><!-- 是否只读 -->
<property name="defaultSchema">TESTDB</property>
</user>
schema.xml配置数据库
通过配置schema.xml可以配置多个主从节点,并可以配置读写分离的方式。
<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="123456">
<!-- 从节点的配置信息 -->
<readHost host="hostS1" url="" user="" password=""/>
</writeHost>
</dataHost>
dataHost的balance时负载均衡类型
- 值为0时,不开启读写分离
- 值为1时,所有的readHost和备用writeHost参与select语句的负载均衡
- 值为2时,读操作随机分发
- 值为3时,所有的读操作分发到readHost,writeHost不承担读操作
配置垂直分库(多数据源):
MyCAT实现分库的原理是根据“拦截”,但凡有关联(会出现join),就要在同一个库。
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="customer" dataNode="dn2"/>
</schema>
<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
/> -->
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<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="localhost1:3306" user="root"
password="123456">
</writeHost>
<writeHost host="hostM2" url="localhost2:3306" user="root"
password="123456">
</writeHost>
</dataHost>
根据配置,对customer表的操作就会在dn2上进行。
水平分表
rule.xml配置分表规则:
<tableRule name="rule1">
<rule>
<columns>id</columns>
<!-- 根据id取模分表 -->
<algorithm>mod_long</algorithm>
</rule>
</tableRule>
schema.xml中的rule配置:
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<!-- 对order表进行拆分 -->
<table name="order" dataNode="dn1,dn2" rule="rule1"/>
</schema>
这里的拆分是根据id对机器数取模,这样保证平均。
查询操作时,Mycat先对语句进行分析,随后将SQL发送到真实的数据库,并对结果处理并返回,以此实现跨库查询。
但如果对oder表进行join查询,将会报错。
解决办法是,对相关的表也进行同样的分表。
如:
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<!-- 对order表进行拆分 -->
<table name="order" dataNode="dn1,dn2" rule="rule1">
<childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="id"/>
</table>
</schema>
parentKey指的是父表的id,joinKey是指订单详情表与订单表join操作的列。
全局表
有一种表每个库都需要使用并且不可拆分,如字典表。这种表就设置为全局,每个数据库都一样,所有写操作会同步。
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<!-- 对order表进行拆分 -->
<table name="order" dataNode="dn1,dn2" rule="rule1">
</table>
<table name="dict" dataNode="dn1,dn2" type="global">
</table>
</schema>
设置type为global即可设置为全局表。
全局序列
全局序列,有三种方式。
-
本地文件。将序列交给MyCAT管理,不推荐,这样抗风险能力较差。
-
数据库方式。
在数据库中建一个表,来进行计数累加。mycat预加载一部分号段到mycat内存中,如果号段用完了,则mycat会再向数据库要一次。如果mycat崩溃,那么当mycat启动后会向数据库重新申请号段。
-
时间戳方式。不推荐,时间戳太长了。
-
自主生成。使用redis单线程的原理,可以生产不重复的主键id。