分片规则概述:node
在数据切分处理中,特别是水平切分中,中间件最终要的两个处理过程就是数据的切分、数据的聚合。选择合适的切分规则,相当重要,由于它决定了后续数据聚合的难易程度,甚至能够避免跨库的数据聚合处理。python
rule.xml配置文件
rule.xml 里面就定义了咱们对表进行拆分所涉及到的规则定义。
咱们能够灵活的对表使用不一样的分片算法,或者对表使用相同的算法但具体的参数不一样。这个文件里面主要有 tableRule 和 function 这两个标签。在具体使用过程当中能够按照需求添加 tableRule 和 function。算法
tableRule 标签
这个标签订义表规则。在 schema.xml配置中使用。数据库
<tableRule name="rule1"> <rule> <columns>id</columns> <algorithm>func1</algorithm> </rule> </tableRule>
name 属性
指定惟一的名字,用于标识不一样的表规则。分布式rule 标签
指定对物理表中的哪一列进行拆分和使用什么路由算法。函数columns 标签
指定要拆分的列名字。测试algorithm 标签
使用 function 标签中的 name 属性。链接表规则和具体路由算法。固然,多个表规则能够链接到同一个路由算法上。table 标签内使用。让逻辑表使用这个规则进行分片。this
function 标签
这个标签订义表规则的具体算法。spa
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"> <property name="mapFile">partition-hash-int.txt</property> </function>
name 属性
指定算法的名字。
class 属性
制定路由算法具体的类名字。日志property 标签
具体算法须要用到的一些属性。
#####################################
下面将介绍 Mycat 目前已有的分片规则,每种规则都有特定的场景,分析每种规则去选择合适的应用到项目中。
<一>分片枚举:
算法说明:
经过在配置文件中配置的可能的枚举 id,本身配置分片,本规则适用于特定的场景,好比有些业务须要按照省
份或区县来作保存,而全国省份区县是固定的,这类业务使用本条规则
<tableRule name="sharding-by-intfile"> <rule> <columns>user_id</columns> <algorithm>hash-int</algorithm> </rule> </tableRule> <function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"> <property name="mapFile">partition-hash-int.txt</property> <property name="type">0</property> <property name="defaultNode">0</property> </function> ##配置文件: partition-hash-int.txt 10000=0 10010=1 DEFAULT_NODE=1
分片函数配置中:
mapFile属性:
配置文件名称。
type属性:
默认值为 0,0 表示 Integer,非零表示 String,全部的节点配置都是从 0 开始,及 0 表明节点 1
defaultNode属性:
默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点。
默认节点的做用:枚举分片时,若是碰到不识别的枚举值,就让它路由到默认节点;若是不配置默认节点(defaultNode 值小于 0 表示不配置默认节点),碰到不识别的枚举值就会报错;
like this:can’t find datanode for sharding column:column_name val:ffffffff
<二>固定分片 hash 算法:
算法说明:
本条规则相似于十进制的求模运算,区别在因而二进制的操做,是取 id 的二进制低 10 位(二进制高位、低位说明:左边为高位,右边为低位),即 id 二进制&1111111111;也就是说从右边数取10位。
此算法的优势在于若是按照十进制取模运算,在连续插入 1-10 时候 1-10 会被分到 1-10 个分片,增大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减小插入事务事务控制难度。
<tableRule name="rule1"> <rule> <columns>user_id</columns> <algorithm>func1</algorithm> </rule> </tableRule> <function name="func1" class="org.opencloudb.route.function.PartitionByLong"> <property name="partitionCount">2,1</property> <property name="partitionLength">256,512</property> </function>
分片函数配置中:
partitionCount属性:
分片个数列表。
partitionLength属性:
分片范围列表。
分区长度:默认为最大 2^n=1024 ,即最大支持 1024 分区;意思就是分片个数 * 分片范围 = 1024。
用法例子:
本例的分区策略:但愿将数据水平分红 3 份,前两份各占 25%,第三份占 50%。(故本例非均匀分区)
|<——————————1024———————————>|
|<——256—>|<——256——>|<————512————->|
| partition0 | partition1 | partition2 |
| 共 2 份,故 count[0]=2 | 共 1 份,故 count[1]=1 |
若是平均分红4份怎么分?
|<——256—>|<——256——>|<——256—>|<——256——>|
<function name="func1" class="org.opencloudb.route.function.PartitionByLong"> <property name="partitionCount">4</property> <property name="partitionLength">256</property> </function>
<三>取模
算法说明:
此种规则很是明确即根据 id 进行十进制求模预算,相比固定分片 hash算法,此种在批量插入时可能存在批量插入单事务插入多数据分片,增大事务一致性难度。
<tableRule name="mod-long"> <rule> <columns>user_id</columns> <algorithm>mod-long</algorithm> </rule> </tableRule> <function name="mod-long" class="org.opencloudb.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">3</property> </function>
<四>范围约定
算法说明:
此分片适用于,提早规划好分片字段某个范围属于哪一个分片,
start <= range <= end.
range start-end ,data node index
K=1000,M=10000.
<tableRule name="auto-sharding-long"> <rule> <columns>user_id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule> <function name="rang-long" class="org.opencloudb.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> <property name="defaultNode">0</property> </function> ##配置文件: autopartition-long.txt K=1000,M=10000. 0-500M=0 500M-1000M=1 1000M-1500M=2 或 0-10000000=0 10000001-20000000=1
分片函数配置中:
mapFile属性:
表明配置文件路径。
defaultNode属性:
超过范围后的默认节点。
全部的节点配置都是从 0 开始,及 0 表明节点 1,此配置很是简单,即预先制定可能的 id 范围到某个分片。
<五>取模范围约束
算法说明:
此种规则是取模运算与范围约束的结合,主要为了后续数据迁移作准备,便可以自主决定取模后数据的节点分布。
<tableRule name="sharding-by-pattern"> <rule> <columns>user_id</columns> <algorithm>sharding-by-pattern</algorithm> </rule> </tableRule> <function name="sharding-by-pattern" class="org.opencloudb.route.function.PartitionByPattern"> <property name="patternValue">256</property> <property name="defaultNode">2</property> <property name="mapFile">partition-pattern.txt</property> </function> ##配置文件: partition-pattern.txt # id partition range start-end ,data node index ###### first host configuration 1-32=0 33-64=1 65-96=2 97-128=3 ######## second host configuration 129-160=4 161-192=5 193-224=6 225-256=7 0-0=7
分片函数配置中:
patternValue属性:
即求模基数。
defaoultNode属性:
默认节点。
mapFile属性:
配置文件路径
配置文件中,1-32 即表明 id%256 后分布的范围,若是在 1-32 则在分区 1,其余类推,若是 id 非数据,则会分配在 defaoultNode 默认节点。
<六>截取数字作 hash 求模范围约束
算法说明:
此种规则相似于取模范围约束,此规则支持数据、符号、字母取模。
<tableRule name="sharding-by-prefixpattern"> <rule> <columns>user_id</columns> <algorithm>sharding-by-prefixpattern</algorithm> </rule> </tableRule> <function name="sharding-by-pattern" class="org.opencloudb.route.function.PartitionByPrefixPattern"> <property name="patternValue">256</property> <property name="prefixLength">5</property> <property name="mapFile">partition-pattern.txt</property> </function> 配置文件: partition-pattern.txt # range start-end ,data node index # ASCII # 8-57=0-9 阿拉伯数字 # 6四、65-90=@、A-Z # 97-122=a-z ###### first host configuration 1-4=0 5-8=1 9-12=2 13-16=3 ###### second host configuration 17-20=4 21-24=5 25-28=6 29-32=7 0-0=7
分片函数配置中:
patternValue属性:
求模基数。
prefixLength属性:
ASCII 截取的位数。
mapFile属性:
配置文件路径
配置文件中,1-32 即表明 id%256 后分布的范围,若是在 1-32 则在分区 1,其余类推此种方式相似方式 取模范围约束 只不过采起的是将分区列中获取前 prefixLength 位列全部 ASCII 码的和进行求模sum%patternValue ;获取的值,在范围内的分片数。
<七>范围求模分片
算法说明:
先进行范围分片,计算出分片组,组内再求模;
优势能够避免扩容时的数据迁移,又能够必定程度上避免范围分片的热点问题。
综合了范围分片和求模分片的优势,分片组内使用求模能够保证组内数据比较均匀,分片组之间是范围分片能够兼顾范围查询。最好事先规划好分片的数量,数据扩容时按分片组扩容,则原有分片组的数据不须要迁移。因为分片组内数据比较均匀,因此分片组内能够避免热点数据问题。
<tableRule name="auto-sharding-rang-mod"> <rule> <columns>id</columns> <algorithm>rang-mod</algorithm> </rule> </tableRule> <function name="rang-mod" class="org.opencloudb.route.function.PartitionByRangeMod"> <property name="mapFile">partition-range-mod.txt</property> <property name="defaultNode">21</property> </function> ##配置文件: partition-range-mod.txt range start-end ,data node group size ##如下配置一个范围表明一个分片组,=号后面的数字表明该分片组所拥有的分片的数量。 0-200M=5 #表明有 5 个分片节点 200M1-400M=1 400M1-600M=4 600M1-800M=4 800M1-1000M=6
分片函数配置中:
mapFile属性:
表明配置文件路径。
defaultNode属性:
超过范围后的默认节点顺序号,节点从 0 开始。
<八>截取数字 hash 解析
算法说明:
此规则是截取字符串中的 int 数值 hash 分片。
<tableRule name="sharding-by-stringhash"> <rule> <columns>user_id</columns> <algorithm>sharding-by-stringhash</algorithm> </rule> </tableRule> <function name="sharding-by-stringhash" class="org.opencloudb.route.function.PartitionByString"> <property name="partitionLength">512</property><!-- zero-based --> <property name="partitionCount">2</property> <property name="hashSlice">0:2</property> </function>
分片函数配置中:
partitionLength属性:
表明字符串 hash 求模基数。
partitionCount属性:
分区数。
hashSlice属性:
hash 预算位,即根据子字符串中 int 值 hash 运算
hashSlice : 0 means str.length(), -1 means str.length()-1
/**
* “2” -> (0,2)
* “1:2” -> (1,2)
* “1:” -> (1,0)
* “-1:” -> (-1,0)
* “:-1” -> (0,-1)
* “:” -> (0,0)
*/
<九>按日期(天)分片
算法说明:
此规则为按天分片。
<tableRule name="sharding-by-date"> <rule> <columns>create_time</columns> <algorithm>sharding-by-date</algorithm> </rule> </tableRule> <function name="sharding-by-date" class="org.opencloudb.route.function.PartitionByDate"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2014-01-01</property> <property name="sEndDate">2014-01-02</property> <property name="sPartionDay">10</property> </function>
分片函数配置中:
dateFormat属性:日期格式
sBeginDate属性:开始日期
sEndDate属性:结束日期
sPartionDay属性:分区天数,即默认从开始日期算起,分隔 10 天一个分区。
若是配置了 sEndDate 则表明数据达到了这个日期的分片后后循环从开始分片插入。
<十>日期范围 hash 分片
算法说明:
思想与范围求模一致,当因为日期在取模会有数据集中问题,因此改为 hash 方法。先根据日期分组,再根据时间 hash 使得短时间内数据分布的更均匀。
优势能够避免扩容时的数据迁移,又能够必定程度上避免范围分片的热点问题要求日期格式尽可能精确些,否则达不到局部均匀的目的。
< tableRule name="rangeDateHash"> <rule> <columns>col_date</columns> <algorithm>range-date-hash</algorithm> </rule> </tableRule> <function name="range-date-hash" class="org.opencloudb.route.function.PartitionByRangeDateHash"> <property name="sBeginDate">2014-01-01 00:00:00</property> <property name="sPartionDay">3</property> <property name="dateFormat">yyyy-MM-dd HH:mm:ss</property> <property name="groupPartionSize">6</property> </function>
分片函数配置中:
sPartionDay属性:
表明多少天分一个分片
groupPartionSize属性:
表明分片组的大小。
<十一>天然月分片
算法说明:
按月份列分区 ,每一个天然月一个分片,格式 between 操做解析的范例。
<tableRule name="sharding-by-month"> <rule> <columns>create_time</columns> <algorithm>sharding-by-month</algorithm> </rule> </tableRule> <function name="sharding-by-month" class="org.opencloudb.route.function.PartitionByMonth"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2014-01-01</property> </function>
分片函数配置中:
dateFormat : 日期字符串格式
sBeginDate : 开始日期。
<十二>按单月小时拆分
算法说明:
此规则是单月内按照小时拆分,最小粒度是小时,能够一天最多 24 个分片,最少 1 个分片,一个月完后下月从头开始循环。每月月尾,须要手工清理数据。
<tableRule name="sharding-by-hour"> <rule> <columns>create_time</columns> <algorithm>sharding-by-hour</algorithm> </rule> </tableRule> <function name="sharding-by-hour" class="org.opencloudb.route.function.LatestMonthPartion"> <property name="splitOneDay">24</property> </function>
分片函数配置中:
splitOneDay : 一天切分的分片数。
<十三>冷热数据分片
算法说明:
根据日期查询日志数据 冷热数据分布 ,最近 n 个月的到实时交易库查询,超过 n 个月的按照 m 天分片。
<tableRule name="sharding-by-date"> <rule> <columns>create_time</columns> <algorithm>sharding-by-hotdate</algorithm> </rule> </tableRule> <function name="sharding-by-hotdate" class="org.opencloudb.route.function.PartitionByHotDate"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sLastDay">10</property> <property name="sPartionDay">30</property> </function>
分片函数配置中:
sPartionDay属性:表明多少天分一个分片
sLastDay属性:表明超过多少天开始按照sPartionDay分片。
<十四>一致性 hash
算法说明:
一致性 hash 预算有效解决了分布式数据的扩容问题。
<tableRule name="sharding-by-murmur"> <rule> <columns>user_id</columns> <algorithm>murmur</algorithm> </rule> </tableRule> <function name="murmur" class="org.opencloudb.route.function.PartitionByMurmurHash"> <property name="seed">0</property> <property name="count">2</property> <property name="virtualBucketTimes">160</property> <property name="weightMapFile">weightMapFile</property> <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> </function>
分片函数配置中:
seed属性: 默认是 0
count属性:
要分片的数据库节点数量,必须指定,不然无法分片。
virtualBucketTimes属性:
一个实际的数据库节点被映射为这么多虚拟节点,默认是 160 倍,也就是虚拟节点数是物理节点数的 160 倍。
weightMapFile属性:
节点的权重,没有指定权重的节点默认是 1。以 properties 文件的格式填写,以从 0 开始到 count-1 的整数值也就是节点索引为 key,以节点权重值为值。全部权重值必须是正整数,不然以 1 代替。
bucketMapPath属性:
用于测试时观察各物理节点与虚拟节点的分布状况,若是指定了这个属性,会把虚拟节点的 murmur hash 值与物理节点的映射按行输出到这个文件,没有默认值,若是不指定,就不会输出任何东西。
<十五>应用指定
算法说明:
此规则是在运行阶段有应用自主决定路由到那个分片。
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)。
<tableRule name="sharding-by-substring"> <rule> <columns>user_id</columns> <algorithm>sharding-by-substring</algorithm> </rule> </tableRule> <function name="sharding-by-substring" class="org.opencloudb.route.function.PartitionDirectBySubString"> <property name="startIndex">0</property><!-- zero-based --> <property name="size">2</property> <property name="partitionCount">8</property> <property name="defaultPartition">0</property> </function>
实例说明: id=05-100000002 在此配置中表明根据 id 中从 startIndex=0,开始,截取 siz=2 位数字即 05,05 就是获取的分区,若是没传默认分配到 defaultPartition