文章目录
- 1.Mycat水平拆分的分片规则
- 2. Mycat水平拆分之范围分片
- 2.1.使用范围分片水平分表的背景
- 2.2.水平分表范围分片案例
- 2.3.准备测试的表结构
- 2.4.配置Mycat实现范围分片的水平分表
- 2.4.1.配置Schema配置文件
- 2.4.2.配置Rule分片规则配置文件
- 2.4.3.配置Server配置文件
- 2.4.4.重启Mycat
- 2.5.写入数据观察水平分表效果
1.Mycat水平拆分的分片规则
Mycat水平分库分表,都是对表中的数据量进行拆分的,将一个数据库中的表数据拆分到多个数据库实例中,并不能实现将一个表在当前数据库中拆成多个表。
Mycat的分片规则都已经写好了,我们直接来调用即可,无需认为编写。
水平拆分主要是根据分片规则进行逻辑上的拆分,常用的水平拆分分片规则如下:
- 范围分片
- 根据表中的数据量大小,决定将表中的数据拆分到那些分片上,例如0~500w条数据拆分到分片1,500w-1000w数据拆分到分片2。
- 取模分片
- 根据数据量与节点数量的求模运算,根据运算结果,决定数据存储的分片,例如插入第50条数据,节点有4个,那么就是50÷4=12余2,余数2就是该条数据写入的分片ID。
- 一致性Hash分片
- 所谓一致性哈希,相同的哈希因子计算值总是被划分到相同的分区表中,不会因为分区节点的增加而改变原来数据的分区位置,有效的解决了分布式数据的拓容问题。
- 枚举分片
- 通过在配置文件中配置可能的枚举值, 指定数据分布到不同数据节点上, 本规则适用于按照省份、性别、状态拆分数据等业务
- 日期分片
- 根据日期时间来进行分库分表,常见的有按月分表,每个月产生一个新表。
2. Mycat水平拆分之范围分片
2.1.使用范围分片水平分表的背景
平台库下有一张表的数据量非常多,目前已经达到了600w行数据,查询效率很低,数据量越大,索引的结构就越高,性能会有所下降。
基于这种情况,我们决定针对这张业务表进行水平分表,分表后,原表的数据量就会被分到多张表中,缓解单表的压力,将该表的数据拆分到多个数据库实例中存放,0500万的数据在分片1中,500100万的数据在分片2中。
水平分表,如果不想将表数据拆分到多个数据库实例中,只想在本库新增一张表,来存放后期产生的数据,这种情况就不能通过Mycat实现了,Mycat只能跨实例分表,无法在本实例下分表。
2.2.水平分表范围分片案例
在db_1数据库下有一张table1表,其数据量已经达到500w行,查询效率较低,现需要对这张表进行水平分表,0500w行的数据写入到分片1的数据库实例中,5001000w行的数据写入到分片2的数据库实例中。
2.3.准备测试的表结构
配置水平分表前,需要将要分的表在所有的分片上创建出来。
如果是生产环境的某张表进行水平分表,比如说表数据400w行都在分片1中读写的,水平分表时,分片1中的数据可以不动,按照范围,400w以后的数据在分表完成后,会自动路由到分片2上,因此只需要在所有的分片上准备好表结构即可,旧数据就在原实例。
当然也可以手动进行分表,就是开发同事会比较麻烦。
分片节点数依旧是2个,还是之前垂直分库分表时使用的两套双主双从集群。
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 table1 (id int,name varchar(10));"
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11 -e "use db_2; create table table1 (id int,name varchar(10));"
2.4.配置Mycat实现范围分片的水平分表
2.4.1.配置Schema配置文件
我们针对table1这张表进行水平分表时,要为其同时指定上两个分片,然后再为其指定分片规则,同时指定两个分片后,Mycat根据分片规则路由到不同的分片上。
[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">
<!--定义逻辑表 将table1这张大表水平拆分到dn1、dn2这两个分片上 并且分片规则使用auto-sharding-long-->
<table name="table1" dataNode="dn1,dn2" rule="auto-sharding-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.4.2.配置Rule分片规则配置文件
在Rule分片规则配置文件中,我们要配置主要是根据表中的那个字段进行范围分片,如果做范围分片的字段也是id字段,就不需要调整这个配置文件,只需要调整范围分片中传入的参数。
如果同时由多个表需要范围分片,并且做范围分片的字段都是不同的,我们也可以自己定义一个分片规则,只是给分片规则改个名而已,然后指定做分片的字段,指定调用哪一个函数即可,范围分片的函数是rang-long,在配置文件下面有显示。
[root@mysql-1 ~]# vim /data/mycat/conf/rule.xml
<!--分片规则的名称-->>
<tableRule name="auto-sharding-long">
<rule>
<!--要对哪个字段进行分片-->>
<columns>id</columns>
<!--使用那种类型的分片 指定某类型分片所对应的函数-->>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<!--特定类型所对应的函数名称-->>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<!--分片规则函数传入的参数 从这里看会传入一个文件 这个文件应该就是要定义的范围-->>
<property name="mapFile">autopartition-long.txt</property>
</function>
范围分片的函数需要把autopartition-long.txt这个文件的内容,作为传参,该文件中定义的就是分片的范围。
该文件的含义:1M=10000 -K=1000,默认参数0500M也就是0500w之间的数据路由到分片1,500-1000M的数据路由到分片2,1000-1500M的数据路由到分片3
=0指的是我们再Schema配置文件中声明的第一个分片dn1,以此类推,Rule配置文件中定义的分片id都是从0开始的。
我们的需求刚好就是0500w和5001000w,并没有说1000-1500W的数据如何路由,并且我们也没有第三个分片节点,因此我们需要配置这个文件,将第三个分片删除,否则启动Mycat将会是啊比,我们也可以根据自己实际的情况来配置分片范围。
[root@mysql-1 conf]# vim autopartition-long.txt
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
2.4.3.配置Server配置文件
[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.4.4.重启Mycat
[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...
2.5.写入数据观察水平分表效果
1)写入0~500W的数据观察是否会落在分片1中
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into table1 (id,name) values (100,'abc');
mysql> insert into table1 (id,name) values (100000,'abc');
0~500W之间的数据成功被分到了分片1这个集群中,水平分表成功。
2)写入0~500W的数据观察是否会落在分片1中
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> insert into table1 (id,name) values (7000000,'abc');
mysql> insert into table1 (id,name) values (9000078,'abc');
500W~1000W之间的数据成功被分到了分片2这个集群中,水平分表成功。
3)在Mycat中通过查询table1表就能看到所有的数据