分库分表和读写分离是 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 上并行操作。
要点:负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限。
评论