MyCat系列十--数据分片之范围求模
MyCat系列十--数据分片之范围求模
是取模运算与范围约束的结合,为先进行范围分片,计算出分片组,再进行组内求模。
具体示例实现的步骤为如下(注:蓝色字体为本示例的相关内容):
- 新建表
CREATE TABLE `t_rang_mod` (
`id` int DEFAULT NULL,
`name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB;
- 配置rule.xml
2.1 配置tableRule 标签
编辑rule.xml文件,增加或者修改如下:
<tableRule name="sharding-rang-mod-test">
<rule>
<columns>id</columns>
<algorithm>rang-mod-test</algorithm>
</rule>
</tableRule>
2.2 配置function 标签
编辑rule.xml文件,增加或者修改如下:
<function name="rang-mod-test" class="io.mycat.route.function.PartitionByRangeMod">
<property name="mapFile">partition-range-mod-test.txt</property>
<property name="patternValue">2</property>
<property name="defaultNode">0</property>
</function>
范围求模算法的相关property 子标签含义如下:
2.2.1 mapFile
分片配置文件名,需要在此定义的文件中进行范围设置。
例如:
<property name="mapFile">partition-range-mod-test.txt</property>
2.2.2 patternValue
求模基数。
例如:
<property name="patternValue">2</property>
2.2.3 defaultNode
默认节点。
例如:
<property name="defaultNode">0</property>
- 创建partition-range-mod-test.txt文件
在conf目录下,新建
partition-range-mod-test.txt,并输入以下文本:
1-1M=1
2M-3M=2
4M-5M=1
代表:
- 等号前指定了一个不相交的范围,这个范围表示的是目标分区字段的值将会落在哪个范围内;
- 等号后面有一个数字,需要注意的是,这个数字并不是指数据库节点id,而是当前范围将会占用的数据库节点数目,比如这里的范围1-1M内的数据将会被分配到1个数据库节点上,而范围2M-3M内的数据将会被分配到2个数据库节点上;也就是说,等号后面指定了当前范围所需要使用的分片数,而该范围的数据在这几个数据库节点的分布方式是通过取模的方式来实现的。总体上来说,在大的方向上,整体数据被切分为多个范围,然后在每个范围内,数据根据取模的方式分配到不同的数据节点上。
- 以上总分片数就是4=1+2+1,所以接下来,需要定义对应的4个dataNode。
- 配置schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="testdb" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="true">
<table name="t_rang_mod" dataNode="dn1,dn2,dn3,dn4" rule="sharding-rang-mod-test"></table>
</schema>
<dataNode name="dn1" dataHost="localhost" database="db_user_1" />
<dataNode name="dn2" dataHost="localhost" database="db_user_2" />
<dataNode name="dn3" dataHost="localhost" database="db_user_3" />
<dataNode name="dn4" dataHost="localhost" database="db_user_4" />
<dataHost name="localhost" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="localhost" url="localhost:3306" user="root"
password="123456">
</writeHost>
</dataHost>
</mycat:schema>
dataNode:数据节点,配置了dn1,dn2,dn3,dn4,分别指向不同的服务器及其数据库,这里也就是数据分片的配置。本示例为了简单,配置到同一台服务器的不同数据库上。
- 验证
注意:在示例中,由于配置的总分片数为4分片,如果在schema.xml中配置少于4个dataNode,则重启MyCat服务,会在日志wrapper.log中看到如下错误信息:
Caused by: io.mycat.config.util.ConfigException: Illegal table conf : table [ T_RANG_MOD ] rule function [ rang-mod-test ] partition size : 4 > table datanode size : 3, please make sure table datanode size = function partition size
重启MyCat服务。然后,我们进行如下SQL语句执行验证:
insert into t_rang_mod(id,name)
values (1,'张丽丽'),(10000,'王洁'), (20000,'李梦'),(25001,'赵可可'),(30000,'赵雪'),(40000,'高明'), (50000,'齐凯'),(80000,'刘娟');
select * from t_rang_mod;
在MySQL的服务器上进行查询,如下所示:
select * from db_user_1.t_rang_mod;
select * from db_user_2.t_rang_mod;
select * from db_user_3.t_rang_mod;
select * from db_user_4.t_rang_mod;
从以上查询结果,可以看到数据的分片存储情况是正确的,见下面表格:
范围 | 分片 | dataNode | 测试数据(取模2) |
1-1M | 1 | dn1 | 1,10000 |
2M-3M | 2 | dn2 | 20000,30000 |
dn3 | 25001 | ||
4M-5M | 1 | dn4 | 40000,50000 |
其它 | dn1 | 80000 |
- 其它配置验证
在以上正确配置的基础上,我们修改一些标签的配置值为其它不同的值,进行一些验证。
注:以下修改仅限于提及的子标签配置,而其它配置保持不变。
6.1 defaultNode
编辑rule.xml文件,增加或者修改如下:
<property name="defaultNode">2</property>
重启MyCat服务。然后,我们进行如下SQL语句执行验证:
delete from t_rang_mod;
insert into t_rang_mod(id,name)
values (80001,'章问');
在MySQL的服务器上进行查询,如下所示:
select * from db_user_1.t_rang_mod;
select * from db_user_2.t_rang_mod;
select * from db_user_3.t_rang_mod;
select * from db_user_4.t_rang_mod;