MyCat系列七--数据分片之固定分片
MyCat系列七--数据分片之固定分片
固定分片规则类似于十进制的求模运算,区别在于固定分片是二进制的操作,是取 id 的二进制低 10 位。
此算法的优点在于如果按照 10 进制取模运算,在连续插入 1-10 时候 1-10 会被分到 1-10 个分片,增大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减少插入事务事务控制难度。
具体示例实现的步骤为如下(注:蓝色字体为本示例的相关内容):
- 新建表
CREATE TABLE `t_user2` (
`id` int DEFAULT NULL,
`name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB;
- 配置rule.xml
2.1 配置tableRule 标签
编辑rule.xml文件,增加或者修改如下:
<tableRule name="user2_rule">
<rule>
<columns>id</columns>
<algorithm>user2_func</algorithm>
</rule>
</tableRule>
2.2 配置function 标签
编辑rule.xml文件,增加或者修改如下:
<function name="user2_func" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">2,1</property>
<property name="partitionLength">256,512</property>
</function>
固定分片算法的相关property 子标签含义如下:
2.2.1 partitionCount
分片个数列表。
例如:
<property name="partitionCount">2,1</property>
2.2.2 partitionLength
分片范围列表。
例如:
<property name="partitionLength">256,512</property>
分区长度:默认为最大 2^10=1024 ,即最大支持 1024 分区。需要满足如下约束条件:
partitionCount,partitionLength两个数组的长度必须是一致的,且满足如下公式:
1024 = sum((partitionCount[i]*partitionLength[i]))
也就是说,partitionCount和 partitionLength两个向量的点积恒等于 1024。
本示例的分区策略:将数据水平分成 3 份,前两份各占 25%,第三份占 50%。(本例非均匀分区)
|<———————1024———————————>|
|<—-256—>|<—-256—>|<———-512————>|
| partition0 | partition1 | partition2 |
也就是说,以上分为三个分区:0-255,256-511,512-1023。
- 配置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_user2" dataNode="dn1,dn2,dn3" rule="user2_rule"></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" />
<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,分别指向不同的服务器及其数据库,这里也就是数据分片的配置。本示例为了简单,配置到同一台服务器的不同数据库上。
- 验证
重启MyCat服务。然后,我们进行如下SQL语句执行验证:
insert into t_user2(id,name)
values (1,'张丽丽'),(2,'王洁'), (3,'李梦'),(4,'赵雪'),(5,'高明'), (6,'齐凯'),(7,'刘娟'),(934501,'黎志国'),(80200,'贾理');
select * from t_user2;
在MySQL的服务器上进行查询,如下所示:
select * from db_user_1.t_user2;
select * from db_user_2.t_user2;
select * from db_user_3.t_user2;
从以上查询结果,可以看到数据的分片存储情况,接下来,让我们手工验证一下是否正确。
例如,验证934501,该数字的二进制为:11100100001001100101,取低 10 位:1001100101,再换算为10进制为613。依据上述配置方式的存储,应该存储在第三个分片节点上。
- 其它配置验证
在以上正确配置的基础上,我们修改一些标签的配置值为其它不同的值,进行一些验证。
注:以下修改仅限于提及的子标签配置,而其它配置保持不变。
5.1 partitionCount & partitionLength
编辑rule.xml文件,进行平均分片。如下所示:
<property name="partitionCount">4</property>
<property name="partitionLength">256</property>
编辑schema.xml文件,增加dataNode(dn4)的相关配置:
<table name="t_user2" dataNode="dn1,dn2,dn3,dn4" rule="user2_rule"></table>
<dataNode name="dn4" dataHost="localhost" database="db_user_4" />
注意:如果不增加对应的dataNode(dn4),重启MyCat后,进行如下SQL执行将会报告错误:
登录数据库,创建相应的数据库及其表:
CREATE DATABASE `db_user_4`;
CREATE TABLE `t_user2` (
`id` int DEFAULT NULL,
`name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB;
编辑schema.xml文件,增加dataNode(dn4)的相关配置后,重启MyCat服务。然后,我们进行如下SQL语句执行验证:
delete from t_user2;
insert into t_user2(id,name)
values (1023,'夏美娟'),(954501,'齐国'),(60800,'贾四平'),(152830,'刘亚平'),(852543,'杨娜娜');
在MySQL的服务器上进行查询,如下所示:
select * from db_user_1.t_user2;
select * from db_user_2.t_user2;
select * from db_user_3.t_user2;
select * from db_user_4.t_user2;
十进制 | 二进制 | 二进制低10位 | 低10位转十进制 | 对应分片节点 |
954501 | 11101001000010000101 | 0010000101 | 133 | 1 |
152830 | 100101010011111110 | 0011111110 | 254 | 1 |
60800 | 1110110110000000 | 0110000000 | 384 | 2 |
852543 | 11010000001000111111 | 1000111111 | 575 | 3 |
1023 | 1111111111 | 1111111111 | 1023 | 4 |