分库分表和读写分离是mycat提供的两种功能,下文将分别介绍如何落地。
1.分库分表
1.修改schema.xml
将以下配置复制到文件中。可变配置请参照修改。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- name:server中配置的mycat服务名 -->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- name:表名 datanode 是数据库别名 意思是 dn1,dn2中的user表 在mycat服务中生成,所以需要在datanode中的数据库都需要有user表 rule则是分片策略 而mod-long为分片策略-->
<table name="user" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long" />
</schema>
<!-- dn1 dn2对应着上面配置的datanode datahost是下面配置数据源的别名 database:l连接到的mysql服务的test数据库 -->
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataNode name="dn2" dataHost="localhost2" database="test" />
<!-- name对应着上面 datehost中配置 指定datahost的数据源 -->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="root">
</writeHost>
</dataHost>
<dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostS2" url="192.168.2.134:3306" user="root"
password="123">
</writeHost>
</dataHost>
</mycat:schema>
复制代码
2.效果
当我们往mycat服务插入一条时,在数据库,dn1和dn2中轮着插入一条数据。
2.读写分离
1.修改schema.xml
将以下配置复制到文件中。可变配置请参照修改。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- auto sharding by id (long) -->
<table name="user" primaryKey="id" autoIncrement="true" dataNode="dn1" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="root">
<readHost host="hostM1" url="192.168.2.134:3306" user="root" password="123">
</readHost>
</writeHost>
</dataHost>
</mycat:schema>
复制代码
2.效果
读和写分别操作不同的数据库。
3.引申
楼主被面试问到了好几次 :mycat是主库数据复制到从库和直接执行sql操作从库有什么不同?
1.答案
因为主库通过io的形式发送binary log 到从库的relay log中,从库的relay log存放在 os 缓存中。因为是io操作,所以比执行sql更快。
2.复制的原理概括
- master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
- slave将master的binary log events拷贝到它的中继日志(relay log);
- slave重做中继日志中的事件,将更改应用到自己的数据上。
3.复制的原理详解
- 该过程的第一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
- 下一步就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。 SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
- 此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。
要点:负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限。