mycat介绍
- 一个彻底开源的,面向企业应用开发的大数据库集群
- 支持事务、ACID、可以替代MySQL的加强版数据库
- 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
- 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
- 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
- 一个新颖的数据库中间件产品
长期规划2.0
- 完全实现分布式事务,完全的支持分布式。
- 通过Mycat web(eye)完成可视化配置,及智能监控,自动运维。
- 通过mysql 本地节点,完整的解决数据扩容难度,实现自动扩容机制,解决扩容难点。
- 支持基于zookeeper的主从切换及Mycat集群化管理。
- 通过Mycat Balance 替代第三方的Haproxy,LVS等第三方高可用,完整的兼容Mycat集群节点的动态上下线。
- 接入Spark等第三方工具,解决数据分析及大数据聚合的业务场景。
- 通过Mycat智能优化,分析分片热点,提供合理的分片建议,索引建议,及数据切分实时业务建议。
总结
Mycat 是一个数据库的中间件,支持各种常规的MySQL、Oracle、DB2、SQL Server、PostgreSQL的支持,支持分库分表等分布式下的业务架构,让前端开发可以几乎透明.
准备
需要环境
1. JDK:建议是1.7及其以上
2. Mysql:必须是5.5及其以上
3. mycat1.6 linux源码
JDK安装
yum install java-1.8.0-openjdk.x86_64 ;
# 查看版本
java -version
mysql
mysql安装这部分不说了
我自己安装的是mysql5.7
拓扑结构
- 两张表users和item,三个数据库db01,db02,db03(三个库在一个数据库实例上)
- users只在db01中存储
- item表被分割到db02和db03中存储
create database db01;
use db01;
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL default '',
indate DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
在db02和db03中分别创建item表,SQL脚本如下
create database db02;
use db02;
CREATE TABLE item (
id INT NOT NULL AUTO_INCREMENT,
value INT NOT NULL default 0,
indate DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
create database db03;
use db03;
CREATE TABLE item (
id INT NOT NULL AUTO_INCREMENT,
value INT NOT NULL default 0,
indate DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
开始使用
- 先打mycat官方网站上下载安装包,网址为mycat 下载图如下所示:
- 用wget命令下载 wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
- 下载后解压 tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
以下是目录结构
- bin为启动目录
- lib库文件
- logs 日志文件 mycat.log 为运行日志 wrapper.log为启动日志
- conf为配置文件
- 然后在conf目录下编辑service.xml,rule.xml,schema.xml三个文件。
- service.xml主要配置mycat服务的参数,比如端口号,myact用户名和密码使用的逻辑数据库等
- role.xml主要配置路由策略,主要有分片的片键,拆分的策略(取模还是按区间划分等)
- schema.xml文件主要配置数据库的信息,例如逻辑数据库名称,物理上真实的数据源以及表和数据源之间的对应关系和路由策略等。
- 配置如下所示:
- server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sequnceHandlerType">2</property>
<!-- <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-->
<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">1m</property>
<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">true</property>
</system>
<!-- 这部分是我们通过客户端连接需要设置的帐号密码 -->
<user name="root">
<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>
- role.xml
该路由表表明采用mod2的方式进行路由。通过下面可知是对item表的id键进行取模分表的,取模分到db02和db03,而users表直接路由到db01中。
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="role1">
<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>
</mycat:rule>
- schema.xml 数据库的url,usename,password按实际情况填写。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 设置表的存储方式.schema name="TESTDB" 与 server.xml中的 TESTDB 设置一致 -->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="users" primaryKey="id" dataNode="node_db01" />
<table name="item" primaryKey="id" dataNode="node_db02,node_db03" rule="role1" />
</schema>
<!-- 设置dataNode 对应的数据库,及 mycat 连接的地址dataHost -->
<dataNode name="node_db01" dataHost="dataHost01" database="db01" />
<dataNode name="node_db02" dataHost="dataHost01" database="db02" />
<dataNode name="node_db03" dataHost="dataHost01" database="db03" />
<!-- mycat 逻辑主机dataHost对应的物理主机.其中也设置对应的mysql登陆信息 -->
<dataHost name="dataHost01" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="server1" url="127.0.0.1:3306" user="root" password="123456"/>
</dataHost>
</mycat:schema>
启动测试
- 运行mycat
可以运行 bin/mycat status 查看运行状态
验证结果
- 在命令行访问mycat逻辑数据库,采用如下的命令:
mysql -uroot -p123456 -h127.0.0.1 -P8066 -DTESTDB
-u 用户名
-p 密码
-h 指定登陆ip
-P 指定登陆端口
-D 指定登陆数据库
- 现在通过数据库查询数据库和表,发现只有逻辑数据库TESTDB而不是db01, db02, db03;而且表也是统一显示的,而不是分布在不同的实际数据库中。参考图片如下:
-现在在访问Mycat在数据库中插入数据,看数据能否按照前面配置的路由规则进行分表。 - 现在执行如下的SQL语句进行数据的插入。
insert into users(name,indate) values('kk',now());
insert into users(name,indate) values('ss',now());
insert into item(id,value,indate) values(1,100,now());
insert into item(id,value,indate) values(2,100,now());
-然后在mycat上查看是否插入成功,下图显示插入成功。
- 登陆实际的数据库,查看分表是否成功。下图显示分表成功
图上显示,插入的users表中的数据全部在db01中,而item表中的数据通过Id取模后均匀的分布在db02和db03中。这样就根据实际的路由策略进行了分表。 - 测试完成!!~ 对数据库进行了分库分表!