Mycat可以理解为数据库的服务代理,通过mycat,我们可以实现数据库的分库分表和读写分离,同时可以像连接一个简单的服务数据库服务器一样进行数据库的增删改查。
mycat的安装
//下载
wget http://dl.mycat.org.cn/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
//解压
tar -xzvf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
配置介绍
server.xml
系统配置信息。
system 标签:例如字符集、线程数、心跳、分布式事务开关等等。
user 标签:配置登录用户和权限。
<!--登录账户-->
<user name="root" defaultAccount="true">
<!--密码-->
<property name="password">123456</property>
<!--指定schemas-->
<property name="schemas">test</property>
</user>
schema.xml
schema 在MySQL里面可以理解为数据库。
schema.xml 包括逻辑库、表、分片规则、分片节点和数据源,可以定义多个 schema。
有三个主要的标签(table、dataNode、dataHost)
<!--配置schema checkSQLschema:在查询 SQL 中去掉逻辑库名; sqlMaxLimit:自动加上 limit 控制数据的返回-->
<schema name="test" checkSQLschema="true" sqlMaxLimit="100">
<!--配置逻辑表 dataNode:数据库分片节点 rule:分片规则-->
<table name="customer" primaryKey="id" dataNode="test1,test2,test3" rule="rang-long-cust" />
<!--配置逻辑表 -->
<table name="order_info" dataNode="test1,test2,test3" rule="rang-long-cust" >
<!--配置ER表,即存在从属关系的表 -->
<childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="order_id"/>
</table>
</schema>
这里介绍一下primarykey属性:指定该逻辑表对应真实表的主键。MyCat 会缓存主键(通过 primaryKey 属性配置)与具体 dataNode 的信息。当分片规则(rule)使用非主键进行分片时,那么在使用主键进行查询时,MyCat 就会通过缓存先确定记录在哪个 dataNode 上,然后再在该 dataNode 上执行查询。如果没有缓存/缓存并没有命中的话,还是会发送语句给所有的 dataNode
<!--name:名称,dataHost:物理主机,database:物理库 -->
<dataNode name="test1" dataHost="host1" database="test" />
<dataNode name="test2" dataHost="host2" database="test" />
<dataNode name="test3" dataHost="host3" database="test" />
<!--dataHost:配置物理主机信息 -->
<!--
balance:负载的配置,决定select 语句的负载
0:不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
1:所有读操作都随机发送到当前的 writeHost 对应的 readHost 和备用的 writeHost
2:所有的读操作都随机发送到所有的 writeHost,readHost 上
3:所有的读操作都只发送到 writeHost 的 readHost 上
-->
<!--
writeType:读写分离的配置,决定update、delete、insert 语句的负载
0:所有写操作都发送到可用的 writeHost 上(默认第一个,第一个挂了以后发到第二个)
1:所有写操作都随机的发送到 writeHost
-->
<!--
switchType:主从切换配置
-1:表示不自动切换
1:默认值,表示自动切换
2:基于 MySQL 主从同步的状态决定是否切换,心跳语句为 show slave status
3:基于MySQL galera cluster 的切换机制(适合集群)(1.4.1),心跳语句为 show status like 'wsrep%'
-->
<dataHost name="host1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.1.106:3306" user="root"
password="123456">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
<dataHost name="host2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.1.100:3306" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="host3" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.1.103:3306" user="root"
password="123456">
</writeHost>
</dataHost>
rule.xml
指定分片规则
<!--分片规则-->
<tableRule name="rang-long-cust">
<rule>
<columns>id</columns>
<algorithm>func-rang-long-cust</algorithm>
</rule>
</tableRule>
<!--分片算法-->
<function name="func-rang-long-cust"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">rang-long-cust.txt</property>
</function>
rang-long-cust.txt(名称自定义,跟分片算法对应)
分片配置
0-10000=0
10001-20000=1
20001-100000=2
关于mycat分库分表的一些问题
1.非分片字段的条件的查询:对于非分片字段的查询,mycat会把SQL语句发给所有的的数据节点进行SQL语句的查询,然后汇集结果返回
2:对于分页查询:mycat会进行语句的改写,然后进行结果并集,排序返回结果;如: select * from test order by id limit m,n; mycat发给所有的数据节点的sql是:select * from test order by id limit 0,m+n;并集所有数据节点的结果后排序再把结果返回。
3.关联查询:分两种情况,如果是ER表的话,会在当前的数据节点把关联的记录获取;如果不是er表的话,会把驱动表的记录获取后,把关联条件的值发到所有的数据节点获取关联的数据
4.事务:通过XA实现(通过两阶段提交实现)
5.用了mycat实现分库表的数据库表,尽量不要在物理节点上进行数据的处理,所有的数据操作都应该在mycat上进行处理,否则可能会出现数据查询不出来的情景(分片规则)