Mycat 概述
Mycat是一个开源的分布式数据库系统,而Mycat 后面连接的MySQL Server,就好象是MySQL 的存储引擎,Mycat 本身并不存储数据,数据是在后端的MySQL 上存储的,因此数据可靠性以及事务等都是MySQL 保证的。可以把它看作是一个数据库代理,用MySQL 客户端工具和命令行访问。其核心功能是分表分库,即将一个大表水平分割为N 个小表,存储在后端MySQL 服务器里或者其他数据库里。而在最终用户看来,无论是那种存储方式,在Mycat 里,都是一个传统的数据库表,支持标准的SQL 语句进行数据的操作。
Mycat 是一个强大的数据库中间件,不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多租户应用开发、云平台基础设施、让架构具备很强的适应性和灵活性。
Mycat原理
Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
常见概念
逻辑库 (schema)
通常对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道数据库的概念,所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。
逻辑表( table )
既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。
分片表
分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的数据。
非分片表
一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。
ER 表
ER表是为了解决跨分片进行表的关联查询的,有关联关系的表放到一个分片里,没关联关系的随意,
场景:经常会有两张表互相进行join查询,假如说A表已经呗我们分模了(例如我们已经对A表进行了垂直分表或者枚举分片),B表作为儿子表要随父亲A被分配到一个切片里,以例如关联操作。
例如:
A join B ON a.xx=b.yy(yy是B表的关联条件,xx是A表的关联条件)
配置方法:
<table name="A" dataNode="sh1,sh2" rule="mod-long">
<childTable name="B" joinKey="yy" parentKey="xx" />
</table>
全局表
一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动,字典表具有以下几个特性:
• 变动不频繁;
• 数据量总体变化不大;
• 数据规模不大,很少有超过数十万条记录。
对于这类的表,在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,所以Mycat 中通过数据冗余来解决这类表的join,即所有的分片都有一份数据的拷贝,所有将字典表或者符合字典表特性的一些表定义为全局表。
数据冗余是解决跨分片数据join 的一种很好的思路,也是数据切分规划的另外一条重要规则。
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="db1">
<table name="test" primaryKey="id" type="global" dataNode="sh1,sh2" />
</schema>
测试mycat
mycat下载地址
http://dl.mycat.org.cn/
连接MySQL 8遇到的问题
目前Mycat仍主要面对MySQL 5.5、5.6、 5.7版,对最新的MySql 8尚未完全支持,需要用户对MySQL 8和Mycat的配置进行一系列的修改。
1、Mycat的加密方式为mysql_native_password,MySQL 8的默认加密方式为caching_sha2_password。
解决方案:看了很多别人的办法,改驱动jar包、改my.cnf、改url连接,太麻烦了!
下面这个方法我觉得最方便!其实就是单独创建一个mycat用户做连接,设置其加密方式为mysql_native_password,并赋予权限。
CREATE USER 'root'@'%' IDENTIFIED BY 'mycat';
ALTER USER ''root'@'%' IDENTIFIED WITH mysql_native_password BY 'mycat';
GRANT ALL PRIVILEGES ON *.* TO ''root'@'%';
FLUSH PRIVILEGES;
2.mycat连接mysql8.0以上时需要升级驱动版本 lib文件夹下
3.使用命令连接Mycat报错密码错误
解决方案:增加加密方式参数,如:mysql -uroot -p -P8066 -h*...* --default-auth=mysql_native_password。
Mycat配置
1、schema.xml
这个文件是Mycat最重要的配置文件,负责管理库、表、分片规则、DataNode、DataSource。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
<table name="test" dataNode="dn1,dn2,dn3" rule="auto-sharding-long">
</table>
</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="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="jdbc:mysql://x.x.x.x:3306?useSSL=false&serverTimezone=UTC&" user="root" password="123456">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3306" user="root" password="123456"/> -->
</dataHost>
</mycat:schema>
2、server.xml
Server.xml保存了Mycat需要的所有的系统配置信息,代码映射为SystemConfig类。
server.xml文件修改
<system>
<property name="charset">utf8</property>
<property name="useHandshakeV10">1</property>
<property name="defaultSqlParser">druidparser</property>
<property name="mutiNodeLimitType">1</property>
<property name="serverPort">8066</property>
<property name="managerPort">9066</property>
<property name="bindIp">0.0.0.0</property>
</system>
<user name="root" defaultAccount="true">
<property name="password">mycat</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
</user>
<property name="useHandshakeV10">1</property>
连接mysql8.0以上要加上
3、rule.xml
rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
具体的分片规则见conf文件夹下autopartition-long.txt
然后在mysql中提前建好配置文件中的数据库和表
启动mycat
去 mycat/bin 目录下 ./mycat start
连接mycat后插入数据
insert into test(id,name) VALUES(11, '测试一');
insert into test(id,name) VALUES(101, '测试二');
insert into test(id,name) VALUES(1001, '测试三');
连接到mysql查看结果
插入规则中不存在的值且没设置默认的分片时报错
分片规则加上默认分片
插入规则中不存在的值时插入到默认分片中
遇到的问题
修改配置文件后启动mycat失败
查看logs目录下的wrapper.log文件
是XML文件的编码问题
设置xml的编码
将<?xml version="1.0" encoding="UTF-8" ?>
修改为<?xml version="1.0" encoding="UTF8" ?>