1 环境说明
1.1 MyCat
使用MyCat 1.5 ALPHA版本 ,下载地址:http://www.mycat.org.cn/
《Mycat 权威指南》 :http://pan.baidu.com/s/1c0QnQBA
本案例使用Windows7 环境,与 Linux 或 Mac 操作基本一致
启动MyCat最主要的几个配置文件:
conf/server.xml 服务器用户、虚拟Sechma、端口等配置信息。
conf/sechma.xml 物理数据库映射。
启动命令
bin/mysql.bat start|restart|stop|console 常用几项内容
日志文件
logs/wrapper.log mycat服务器日志
logs/mycat.log 数据库操作日志,分析数据库操作路由使用。
1.2 MySql
本案例使用Mysql 5.5 Windows 64 一主一从模式
具体搭建方案参考:
Mysql Windows 发布多个实例 http://www.cnblogs.com/kaye0110/p/5134452.html
Mysql Binlog 主从模式配置 与 验证 http://www.cnblogs.com/kaye0110/p/5134580.html
2 MyCat 主从配置
2.1 sechma.xml
<!-- 使用 mycat 虚拟schema TESTDB -->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 映射到实体表 aaa ruleRequired="false" 不使用分片规则,直接放一个物理库中写 -->
<table name="aaa" primaryKey="ID" dataNode="dn1" ruleRequired="false" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="mycat_sync_test" />
<dataNode name="dn2" dataHost="localhost1" database="mycat_sync_test" />
<!-- 物理数据库结点配置 少许例举几个参数说明,具体参考 《Mycat 权威指南》
balance="1"
1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
2. balance="1",全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
3. balance="2",所有读操作都随机的在writeHost、readhost上分发。
4. balance="3",所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力,注意balance=3只在1.4及其以后版本有,1.3没有。
writeType="0"
1. writeType="0", 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
2. writeType="1",所有写操作都随机的发送到配置的writeHost。
slaveThreshold="100" 心跳时间
-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 配置主要写入物理库 M1 -->
<writeHost host="hostM1" url="localhost:3306" user="root" password="root123">
<!-- 读写分离对应的物理库 S1 -->
<readHost host="hostS1" url="localhost:3307" user="root" password="root123" />
</writeHost>
</dataHost>
3 MyCat 验证
3.1 Insert 验证
使用mysql 命令登陆mycat 服务,mycat默认操作端口 8066 ,管理端口9066
用户名、sechma 要在 conf/server.xml 中进行配置
mysql -u test -ptest -P 8066
mysql> use TESTDB
建议所有SQL语句都带上column list ,以后切换成分片表时,mycat需要根据指定的规则进行partition table操作。
mysql> insert into aaa values ( 1,'hello 1');
ERROR 1064 (HY000): partition table, insert must provide ColumnList
执行 insert SQL
mysql> insert into aaa (id,context) values (5 , 'hell world5');
Query OK, 1 row affected (0.01 sec)
查看 logs/mycat.log
第一句应该是接入数据库操作指令
01/17 09:57:13.038 DEBUG [$_NIOREACTOR-1-RW] (ServerQueryHandler.java:56) -ServerConnection [id=3, schema=TESTDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=TESTDB]insert into aaa (id,context) values (5 , 'hell world5')
第二句应该是根据conf/sechma.xml 配置,确认 insert into 语句在dn1 结点执行
01/17 09:57:13.039 DEBUG [$_NIOREACTOR-1-RW] (NonBlockingSession.java:113) -ServerConnection [id=3, schema=TESTDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=TESTDB]insert into aaa (id,context) values (5 , 'hell world5'), route={
1 -> dn1{insert into aaa (id,context) values (5 , 'hell world5')}
} rrs
第三句应该反应了SQL执行操作
01/17 09:57:13.040 DEBUG [$_NIOREACTOR-1-RW] (MySQLConnection.java:445) -con need syn ,total syn cmd 1 commands SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;schema change:false con:MySQLConnection [id=2, lastTime=1452995833039, user=root, schema=mycat_sync_test, old shema=mycat_sync_test, borrowed=true, fromSlaveDB=false, threadId=23, charset=utf8, txIsolation=0, autocommit=true, attachment=dn1{insert into aaa (id,context) values (5 , 'hell world5')}, respHandler=SingleNodeHandler [node=dn1{insert into aaa (id,context) values (5 , 'hell world5')}, packetId=0], host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
3.2 Select 验证
mysql> select * from aaa;
+----+-------------+
| id | context |
+----+-------------+
| 1 | hello 1 |
| 2 | hello 2 |
| 3 | hello3 |
| 4 | hello4 |
| 5 | hell world5 |
+----+-------------+
5 rows in set (0.05 sec)
查看logs/mycat.log
第一句 hit cache ,后续再做深入研究吧
01/17 10:05:06.145 DEBUG [$_NIOREACTOR-1-RW] (EnchachePool.java:70) -SQLRouteCache hit cache ,key:TESTDBselect * from aaa
第二句 mycat 直接指到 dn1 的数据源
01/17 10:05:06.145 DEBUG [$_NIOREACTOR-1-RW] (NonBlockingSession.java:113) -ServerConnection [id=3, schema=TESTDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=TESTDB]select * from aaa, route={
1 -> dn1{SELECT *
FROM aaa
LIMIT 100}
} rrs
第三句 根据conf/schema.xml配置将读取 hostS1 的数据库,S1 为readHost
01/17 10:05:06.146 DEBUG [$_NIOREACTOR-1-RW] (PhysicalDBPool.java:452) -select read source hostS1 for dataHost:localhost1
第四句 从dn1 读取数据并反回
01/17 10:05:06.146 DEBUG [$_NIOREACTOR-1-RW] (MySQLConnection.java:445) -con need syn ,total syn cmd 1 commands SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;schema change:false con:MySQLConnection [id=17, lastTime=1452996306146, user=root, schema=mycat_sync_test, old shema=mycat_sync_test, borrowed=true, fromSlaveDB=true, threadId=42, charset=utf8, txIsolation=0, autocommit=true, attachment=dn1{SELECT *
FROM aaa
LIMIT 100}, respHandler=SingleNodeHandler [node=dn1{SELECT *
FROM aaa
LIMIT 100}, packetId=0], host=localhost, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
3.2 Select 验证单条记录 select by pk
mysql> select * from aaa where id = '1';
+----+---------+
| id | context |
+----+---------+
| 1 | hello 1 |
+----+---------+
1 row in set (0.05 sec)
再看下MyCat日志
第1次查询时,cache中没有找到对应的数据集
01/17 10:09:35.116 DEBUG [$_NIOREACTOR-1-RW] (EnchachePool.java:76) -SQLRouteCache miss cache ,key:TESTDBselect * from aaa where id = '1'
加入mycat cache了 ,这个理论上是根据配置文件计算出当前记录(by PK)应该存在的物理结点,若配置文件有变化就可以会出现找不到数据的情况?
01/17 10:09:35.164 DEBUG [$_NIOREACTOR-1-RW] (EnchachePool.java:59) -SQLRouteCache add cache ,key:TESTDBselect * from aaa where id = '1' value:select * from aaa where id = '1', route={
1 -> dn1{select * from aaa where id = '1'}
}
接下去的日志基本同上了。
01/17 10:09:35.164 DEBUG [$_NIOREACTOR-1-RW] (NonBlockingSession.java:113) -ServerConnection [id=3, schema=TESTDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=TESTDB]select * from aaa where id = '1', route={
1 -> dn1{select * from aaa where id = '1'}
} rrs
01/17 10:09:35.164 DEBUG [$_NIOREACTOR-1-RW] (PhysicalDBPool.java:452) -select read source hostS1 for dataHost:localhost1
01/17 10:09:35.164 DEBUG [$_NIOREACTOR-1-RW] (MySQLConnection.java:445) -con need syn ,total syn cmd 1 commands SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;schema change:false con:MySQLConnection [id=14, lastTime=1452996575164, user=root, schema=mycat_sync_test, old shema=mycat_sync_test, borrowed=true, fromSlaveDB=true, threadId=40, charset=utf8, txIsolation=0, autocommit=true, attachment=dn1{select * from aaa where id = '1'}, respHandler=SingleNodeHandler [node=dn1{select * from aaa where id = '1'}, packetId=0], host=localhost, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]