MyCat
简介
Mycat 是数据库 中间件 。
1、 数据库中间件
中间件 是一类连接软件组件和应用的计算机软件, 以便于软件各部件之间的沟通 。
例子 Tomcat web 中间件 。
数据库 中间件 连接 java 应用程序和数据库
2、 为什么要用 Mycat
① Java 与数据库紧耦合 。
② 高访问量高并发对数据库的压力 。
③ 读 写请求数据不一致。
作用
1、读写分离
基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT 查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
2、数据分片
垂直拆分 (分库) 、 水平拆分 (分表) 、 垂直 水平拆分 (分库分表)
3、多数据源整合
当一个项目需要用到多种数据源如Oracle、MySQL、SQL Server、 PostgreSQL时,可以利用Mycat进行整合,只需访问Mycat 这一个 数据源就行。
4、数据库路由器
Mycat基于MySQL 实例的连接池复用机制,可以让每个应用最大程度地共享一个MySQL实例的所有连接池,让数据库的并发访问能力大大提升。
原理
Mycat的原理中最重要的一个动 词是“拦截”,它拦截 了用户发送过来的 SQL 语句,首先对 SQL
语句做了 一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库 并将返回的结果做适当的处理,最终再返回给用户 。
逻辑库schema
业务开发人员通常在实际应用中并不需要知道中间件的存在,只需 要关注数据库,所以数据库中间件可以被当作一个或多个数据库集 群构成的逻辑库。
-
name:对应Server.xml中配置的逻辑库名TESTDB
-
checkSQLschema:在SQL语句操作时指定了数据库名称,执行时是否自动去除;true:自动去
除,false:不自动去除。当该值设置为true时,如果我们执行语句select * from TESTDB.travelrecord;则MyCat会把语句修改为select * from travelrecord;即把表示schema的字
符去掉,避免发送到后端数据库执行时报(ERROR 1146 (42S02): Table ‘testdb.travelrecord’
doesn’t exist)。 -
sqlMaxLimit:当该值设置为某个数值时。每条执行的SQL语句,如果没有加上limit语句,MyCat
也会自动的加上所对应的值。例如设置值为100,执行select * from TESTDB.travelrecord;的效果
为和执行select * from TESTDB.travelrecord limit 100;相同设置该值的话,MyCat默认会把查询
到的信息全部都展示出来,造成过多的输出。所以,在正常使用中,还是建议加上一个值,用于减
少过多的数据返回。当然SQL语句中也显式的指定limit的大小,不受该属性的约束。需要注意的
是,如果运行的schema为非拆分库的,那么该属性不会生效。需要手动添加limit语句。 -
dataNode:同时存在,指定默认存储节点,比如建表默认会创建到该节点下,对应dataNode下的
name属性
注意:
逻辑库,与MySQL中的Database(数据库)对应,⼀个逻辑库中定义了所包括的Table。
逻辑表table
既然有逻辑库,就会有逻辑表。在分布式数据库中,对于应用来说,读写数据的表就是逻辑表。逻辑表可以分布在一个或多个分片库中,也可以不分片。
节点主机DataNode
将数据切分后,每个分片节点不一定会独占一台机器,同一台机器上可以有多个分片数据库,这样一个或多个分片节点所在的机器就是节点主机。为了规避单节点主机并发数量的限制,尽量将读写压力高的分片节点均匀地放在不同的节点主机上。
- name:节点名称,可随意填写
- dataHost:对应dataHost标签中name属性值
- database:真实Mysql服务中创建的数据库名称
数据库主机DataHost
数据切分后,每个分片节点(dataNode)不一定都会独占一台机器, 同一机器上面可以有多个分片数据库,这样一个或多个分片节点 (dataNode)所在的机器就是节点主机(dataHost),为了规避单节点主 机并发数限制,尽量将读写压力高的分片节点(dataNode)均衡的放 在不同的节点主机(dataHost)。
1、mysql读写分离集群搭建,要求主从复制至少三台,mycat独立一台
MySQL主从复制:
架构规划
192.168.99.116 master 主节点
192.168.99.117 slave1 从节点
192.168.99.118 slave2 从节点
mycat配置 192.168.99.119
server.xml
<user name="root">
<property name="password">123456</property>
<property name="schemas">XCZDB</property>
</user>
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="XCZDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="testNode">
</schema>
<dataNode name="testNode" dataHost="dtHost" database="t4" />
<dataHost name="dtHost" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<!-- 心跳检测,检测服务器是否宕机 -->
<heartbeat>select user()</heartbeat>
<!--写节点-->
<writeHost host="hostM1" url="192.168.99.116:3306" user="namida" password="Namida@123">
<!--从节点-->
<readHost host="hostS1" url="192.168.99.117:3306" user="namida" password="Namida@123" />
<readHost host="hostS2" url="192.168.99.118:3306" user="namida" password="Namida@123" />
</writeHost>
</dataHost>
</mycat:schema>
cd /usr/local/mycat/bin
mycat console
测试
mycat添加数据
master数据库(连接名sql)
slave1:
slave2
2、mycat分片规则实现,要求有两个主从集群,一台mycat
a、范围分片练习
b、取模分片练习
c、一致性hash分片练习
架构规划
192.168.99.116 master1 主节点
192.168.99.117 slave1 从节点
192.168.99.118 master1 主节点
192.168.99.121 slave2 从节点
a、范围分片练习
规则配置
autopartition-long.txt
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
#1000M-1500M=2
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="XCZDB" checkSQLschema="true" sqlMaxLimit="100" >
<table name="test4" dataNode="dn1,dn2" rule="auto-sharding-long" />
</schema>
<dataNode name="dn1" dataHost="dtHost1" database="t4" />
<dataNode name="dn2" dataHost="dtHost2" database="t4" />
<dataHost name="dtHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<!-- 心跳检测,检测服务器是否宕机 -->
<heartbeat>select user()</heartbeat>
<!--写节点-->
<writeHost host="hostM1" url="192.168.99.116:3306" user="namida" password="Namida@123">
<!--从节点-->
<readHost host="hostS1" url="192.168.99.117:3306" user="namida" password="Namida@123" />
</writeHost>
</dataHost>
<dataHost name="dtHost2" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<!-- 心跳检测,检测服务器是否宕机 -->
<heartbeat>select user()</heartbeat>
<!--写节点-->
<writeHost host="hostM2" url="192.168.99.118:3306" user="namida" password="Namida@123">
<!--从节点-->
<readHost host="hostS2" url="192.168.99.121:3306" user="namida" password="Namida@123" />
</writeHost>
</dataHost>
</mycat:schema>
测试
mycat写入数据
(5000011,test5)
查看master2
b、取模分片练习
修改rule.xml
count 2 代表有2个datanode
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
……
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">2</property>
</function>
修改配置 文件 schema.xml
<schema name="XCZDB" checkSQLschema="true" sqlMaxLimit="100" >
<table name="test4" dataNode="dn1,dn2" rule="mod-long" />
</schema>
mycat添加数据
11,master1
12,master0
master1中出现12
master2中出现11
c、一致性hash分片练习
rule.xml
<tableRule name="sharding-by-murmur">
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
……
<function name="murmur"
class="io.mycat.route.function.PartitionByMurmurHash">
<property name="seed">0</property><!-- 默认是0 -->
<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
<property name="virtualBucketTimes">160</property><!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
<!-- <property name="weightMapFile">weightMapFile</property> 节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 -->
<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property>
用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西 -->
</function>
schema.xml
<schema name="XCZDB" checkSQLschema="true" sqlMaxLimit="100" >
<table name="test4" dataNode="dn1,dn2" rule="sharding-by-murmur" />
</schema>
启动
./mycat console
mycat表test4添加数据
20,test3
21,test33
master1
master2