一.分片算法
1.范围分片(容易出现冷热数据)
根据id所在的区间范围进行分片
<!-- 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>
0-500M=0
500M-1000M=1
1000M-1500M=2
2. 按自然月分片
<!--
columns 标识将要分片的表字段, 字符串类型, 与 dateFormat 格式一致。
algorithm 为分片函数。
dateFormat 为日期字符串格式。
sBeginDate 为开始日期。
sEndDate 为结束日期
注意:节点个数要大于月份的个数
开始日期和结束日期跟年度没有关系,只跟月度有关。不在 10 月和 12 月之间的数据,路由到哪个节点不一定。(本验证的和文档不一样,只能指定年月的被分片,其它均报错)
-->
<table name="sharding_by_month" dataNode="node139_realtime,node47_realtime" rule="qs-sharding-by-month"/>
<tableRule name="qs-sharding-by-month">
<rule>
<columns>create_time</columns>
<algorithm>qs-partbymonth</algorithm>
</rule>
</tableRule>
<function name="qs-partbymonth" class="io.mycat.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2025-10-01</property>
<property name="sEndDate">2025-12-31</property>
</function>
3.取模分片(分布均匀,但是迁移工作量比较大)
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- 数据节点数-->
<property name="count">2</property>
</function>
4.枚举分片(适用于枚举值固定的分片)
将所有可能出现的值列举出来,指定分片。例如:全国 34 个省,要将不同的省的数据存放在不同的节点,可用枚举的方式
<table name="provice_data" dataNode="node139_realtime,node47_realtime" rule="qs-sharding-by-intfile" />
<tableRule name="qs-sharding-by-intfile">
<rule>
<columns>provice</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<!--type:默认值为 0,0 表示 Integer,非零表示 String。-->
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
<property name="defaultNode">0</property>
</function>
策略文件:partition-hash-int.txt
山东=0
河南=1
5.一致性哈希(有效解决分布式数据的扩容问题)
一致性哈希算法的形象解释:https://zhuanlan.zhihu.com/p/24440059
<table name="user_data" primaryKey="id" dataNode="node139_realtime,node47_realtime" rule="sharding-by-murmur" />
<tableRule name="sharding-by-murmur">
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
<function name="murmur" class="io.mycat.route.function.PartitionByMurmurHash">
<property name="seed">0</property>
<property name="count">2</property>
<!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
<property name="virtualBucketTimes">160</property>
</function>
6.固定分片哈希
先求模得到逻辑分片号,再根据逻辑分片号直接映射到物理分片
<table name="sharding_by_long" dataNode="node139_realtime,node47_realtime" rule="sharding-by-long" />
<tableRule name="sharding-by-long">
<rule>
<columns>id</columns>
<algorithm>sharding-by-long</algorithm>
</rule>
</tableRule>
<!--
partitionCount 为指定分片个数列表。
partitionLength 为分片范围列表。
-->
<!--平均分片: 分2片 0~128 128~256-->
<function name="sharding-by-long" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">2</property>
<property name="partitionLength">128</property>
</function>
<!--非平均分片: 分3片 0~256 256~512 512~1024-->
<function name="qs-sharding-by-long" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">2,1</property>
<property name="partitionLength">256,512</property>
</function>
7.取模范围分片
<table name="sharding_by_pattern" primaryKey="id" dataNode="node139_realtime,node47_realtime" rule="sharding-by-pattern" />
<tableRule name="sharding-by-pattern">
<rule>
<columns>id</columns>
<algorithm>sharding-by-pattern</algorithm>
</rule>
</tableRule>
<function name="sharding-by-pattern" class=" io.mycat.route.function.PartitionByPattern">
<property name="patternValue">100</property>
<property name="defaultNode">0</property>
<property name="mapFile">partition-pattern.txt</property>
</function>
#id partition range start-end ,data node index
1-20=0
21-70=1
71-100=2
patternValue 取模基数,这里设置成 100
partition-pattern.txt,一共 3 个节点
id=19%100=19,在 dn1;
id=222%100=22,dn2;
id=371%100=71,dn3
8、范围取模分片(扩容的时候旧数据无需迁移)
<table name="sharding_by_rang_mod" dataNode="122-imall,123-imall,124-imall" rule="qs-sharding-by-rang-mod" />
<tableRule name="qs-sharding-by-rang-mod">
<rule>
<columns>id</columns>
<algorithm>qs-rang-mod</algorithm>
</rule>
</tableRule>
<function name="qs-rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
<property name="mapFile">partition-range-mod.txt</property>
</function>
# range start-end ,data node group size
0-20000=1
20001-40000=2
先范围后取模。Id 在 20000 以内的,全部分布到 dn1。Id 在 20001-40000的,%2 分布到 dn2,dn3
二.切分规则
步骤:
1、找到需要切分的大表,和关联的表
2、确定分片字段(尽量使用主键),一般用最频繁使用的查询条件
3、考虑单个分片的存储容量和请求、数据增长(业务特性)、扩容和数据迁移