文章目录
1.使用取模分片水平分表
平台库下有一张表的数据量非常多,目前已经达到了600w行数据,查询效率很低,数据量越大,索引的结构就越高,性能会有所下降。
基于这种情况,我们决定针对这张业务表进行水平分表,分表后,原表的数据量就会被分到多张表中,缓解单表的压力,将该表的数据拆分到多个数据库实例中存放。
本次我们通过取模分片的方式来对达标进行水平分表。
取模分片指的是根据特定的字段值与分片节点数量进行求模运算,也就是除法运算取余数,根据运算结果中的余数,决定数据写入到哪一个分片中。指定取模分片的字段一定要是数字类型的字段,否则是无法进行运算的。
取模分片例子:
根据id列进行取模分片,写入数据的id为15,分片节点数为2个,运算过程:15/2=7余1,余数为1,取模分片此时就会将这个数据写入到分片2中,因为在Mycat分片中,分片的ID都是从0开始的,余数的值就是要写入对应分片节点的ID号,余数为1就对应分片2这个节点。
2.水平分表取模分片案例
在db_1数据库下有一张table1表,其数据量已经达到500w行,查询效率较低,现需要对这张表进行水平分表,采用取模分片的方法对该表进行水平分表。
2.1.准备测试的表结构
配置水平分表前,需要将要分的表在所有的分片上创建出来。
分片节点数依旧是2个,还是之前垂直分库分表时使用的两套双主双从集群。
sh
1.在两个分片上创建数据库
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11 -e "create database db_2;"
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11 -e "create database db_2;"
2.在两个分片上创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11 -e "use db_2; create table table2 (id int,name varchar(10));"
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11 -e "use db_2; create table table2 (id int,name varchar(10));"
2.2.配置Mycat实现范围分片的水平分表
2.2.1.配置Schema配置文件
我们针对table1这张表进行水平分表时,要为其同时指定上两个分片,然后再为其指定分片规则,同时指定两个分片后,Mycat根据分片规则路由到不同的分片上。
xml
[root@mysql-1 ~]# vim /data/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--定义逻辑库 库名叫做db_shopping 该逻辑库关联dn1这个数据节点-->
<schema name="db_2" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<!--定义逻辑表 将table2这张大表水平拆分到dn1、dn2这两个分片上 并且分片规则使用mod-long-->
<table name="table2" dataNode="dn1,dn2" rule="mod-long"/>
</schema>
<!--定义数据节点 也就是分片 一个分片会关联一个数据主机组 然后对应真实的数据库名称-->
<dataNode name="dn1" dataHost="mysqlcluster-1" database= "db_2" />
<dataNode name="dn2" dataHost="mysqlcluster-2" database= "db_2" />
<!--定义数据主机 在这个标签下定义具体的读写操作路由的数据库实例地址 schema、table划分如何指定的是该数据主机关联的数据节点 那么对应的库、表都会被存储在数据主机定义的数据库实例中-->
<dataHost name="mysqlcluster-1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<!--定义写操作路由的数据库实例-->
<writeHost host="c1-1-master3306" url="192.168.20.11:3306" user="root" password="123456">
<!--定义读操作路由的数据库实例-->
<readHost host="c1-1-slave3308" url="192.168.20.11:3308" user="root" password="123456" />
</writeHost>
<!--备用的主库 也是提供写操作的数据库,当主库c1-1-master3306故障后 备用库开始提供写操作-->
<writeHost host="c1-2-master3306" url="192.168.20.12:3306" user="root" password="123456">
<!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
<readHost host="c1-2-slave3308" url="192.168.20.12:3308" user="root" password="123456" />
</writeHost>
</dataHost>
<dataHost name="mysqlcluster-2" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="c2-1-master3307" url="192.168.20.11:3307" user="root" password="123456">
<readHost host="c2-1-slave3309" url="192.168.20.11:3309" user="root" password="123456" />
</writeHost>
<!--备用主库db3 主库db1故障后 开始提供写操作-->
<writeHost host="c2-2-master3307" url="192.168.20.12:3307" user="root" password="123456">
<!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
<readHost host="c2-2-slave3309" url="192.168.20.12:3309" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
2.2.2.配置Rule分片规则配置文件
在Rule分片规则配置文件中,我们要配置主要是根据表中的那个字段进行范围分片,如果做取模分片的字段也是id字段,就不需要调整这个配置文件,只需要调整取模分片中传入的参数。
注意:做取模分片的字段必须是数字类型的字段。
xml
[root@mysql-1 ~]# vim /data/mycat/conf/rule.xml
<!--分片规则的名称-->>
<tableRule name="mod-long">
<rule>
<!--基于表中那个字段进行分片-->
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<!--特定类型所对应的函数名称-->>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- 分片节点数量 这个值就是取模的分母 id字段会除与这个值 得到的余数就是划分的节点ID -->
<property name="count">2</property>
</function>
2.2.3.配置Server配置文件
xml
[root@mysql-1 ~]# vim /data/mycat/conf/server.xml
<user name="root" defaultAccount="true">
<!--登录用户的密码-->
<property name="password">123456</property>
<!--该用户登录后可以显示那些Schema-->
<property name="schemas">db_2</property>
</user>
2.2.4.重启Mycat
sh
[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...
2.3.写入数据观察水平分表效果
1)插入ID为10和15的两条数据
sql
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into table2 (id,name) values (10,'abc');
mysql> insert into table2 (id,name) values (15,'xbz');
ID10除与分片节点数2,余数为0,那么该条数据会分配至分片1的数据库实例中。
ID15除与分片节点数1,余数为1,那么该条数据会分配至分片2的数据库实例中。
3)在Mycat中通过查询table1表就能看到所有的数据