MyCat的rule分片规则

发布于 2022-07-25  1.83k 次阅读


#1. 取模分片

<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">3</property>
    </function>

配置说明:

属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
count 数据节点的数量

例:现在有三个节点,按照ID字段进行取末运算

id=1 %  3 = 1   => 第二个节点
id=2 %  3 = 2   => 第三个节点
id=3 %  3 = 0   => 第一个节点
id=4 %  3 = 1   => 第二个节点
id=5 %  3 = 2   => 第三个节点

#2. 范围分片

根据指定的字段及其配置的范围与数据节点的对应情况。来决定该数据属于那个分片,配置如下

<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的文件内容:

# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2

含义:0 ~ 500万之间的值,存储在0号数据节点;500万~1000万之间的数据存储在1号数据节点;1000万 ~ 1500万的数据存储在3号数据节点

注:这个配置当存储超过1500万就会报错,需要定义一个默认存储节点来防止,当超过1500万就直接存储到默认节点

<property name="defaultNode">0</property>

配置说明

属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
count 数据节点的数量
mapFile 对应外部配置文件
type 默认值为0;0表示Integer,1表示String
defaultNode 默认节点;枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点;如果没有默认值碰到不识别则报错

#3. 枚举分片

通过在配置文件中配置可能的枚举值,指定数据分布到不同的数据节点上,本规则适用于按照省份或状态等固定数据拆分等业务,配置如下:

<tableRule name="sharding-by-intfile">
        <rule>
            <columns>sharding_name</columns>
            <algorithm>hash-int</algorithm>
        </rule>
    </tableRule>
<function name="hash-int"
              class="io.mycat.route.function.PartitionByFileMap">
        <property name="mapFile">partition-hash-int.txt</property>
        <property name="defaultNode">0</property>
        <property name="type">0</property>
    </function>

partition-hash-int.txt:枚举值与分片节点的对应关系(格式:枚举值 = 分片节点)

湖南=0 #sharding_name=湖南 保存到1号节点
广东=1 #sharding_name=广东 保存到2号节点

#4. 范围取模分片

范围取模分片:该算法先进行范围分片,计算出分片组,再进行组内求模

优缺点:

  • 优点:综合了范围分片和求模分片的优点。分片组内使用求模可以保证组内的数据分布比较均匀,分片组之间采用范围分片可以兼顾范围分片的特点
  • 缺点:在数据范围固定值(非递增值)时,存在不方便拓展的情况,例如将dataNode Group size从2拓展到4时,需要进行数据迁移才能完成

配置:

<tableRule name="auto-sharding-rang-mod">
        <rule>
            <columns>id</columns>
            <algorithm>rang-mod</algorithm>
        </rule>
    </tableRule>
<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
        <property name="mapFile">partition-range-mod.txt</property>
    </function>

partition-range-mod.txt配置格式:

0-500M = 1 #0到500万范围分组有一台机器
500M1-1000M = 2 #500万到1000万分组有两台机器

在上述配置文件中,等号前面的范围代表一个分片组,等号后面的数字代表该分片组所拥有的分片数量

#5. 固定分片hash算法

该算法类似于十进制的求模运算,但是为二进制的操作,取id字段的低10位与1111111111进行&运算

不管id值是什么,位运算最后的结果介于 0 ~ 1023之间

优缺点:

  • 优点:这种策略比较灵活,可以均匀分配也可以非均匀分配,各节点的分配比例和容量大小由partitionCount和partitionLength两个参数决定
  • 缺点:和取模分配类似

配置如下:

<tableRule name="sharding-by-intfile">
        <rule>
            <columns>sharding_id</columns>
            <algorithm>func1</algorithm>
        </rule>
    </tableRule>
<function name="func1" class="io.mycat.route.function.PartitionByLong">
        <property name="partitionCount">2,1</property>
        <property name="partitionLength">256,512</property>
    </function>
  • partitionCount 2,1:将分片列表分成两个区域,第一个区域有两个分片,第二个区域有一个分片
  • partitionLength 256,512:第一个区域每一个分片占256个长度,第二个区域分片占512个长度
在示例中配置的分片策略,将数据水平分成3份,前两份各占25%,第三份占50%

配置说明:

属性
描述
partitionCount 
分片个数列表
partitionLength
分片范围列表
注:
  1. 分片长度:默认最大2^10,为1024
  2. count,length的数组长度必须是一致的

#6. 取模范围分片

含义:该分片规则先进行取模,然后根据取模值所属范围进行分片

优缺点:

  • 优点:可以自主决定取模后的数据节点分布
  • 缺点:拓展麻烦

配置如下:

<tableRule name="sharding-by">
        <rule>
            <columns>id</columns>
            <algorithm>sharding-by-pattern</algorithm>
        </rule>
    </tableRule>
<function name="sharding-by-pattern" class="io.mycat.route.function.PartitionByPattern">
     <property name="mapFile">partition-pattern.txt</property>
     <property name="defaultNode">0</property>
     <property name="patternValue">96</property>
</function>

partition-pattern.txt:

0-32=0
33-64=1
65-96=2

在mapFile配置文件中:1-96即代表id%96后的分布情况。如果1-32则分布在1节点上;如果在33-64则分布在2节点上;65-96则分布在3节点上

#7. 字符串hash求模范围分片

    与取模范围算法类型,该规则支持数值、符号、字母取模,首先截取长度为prefixLength的子串,在对子串中每一个字符的ASCII码求和,然后对求和值进行取模运算,这样计算出子串的分片数

优缺点:

  • 优点:可以自主决定取模后数据的节点分布
  • 缺点:dataNode划分节点是事先建好的,需要拓展时比较麻烦

配置:

<tableRule name="sharding-by-prefixpattern">
        <rule>
            <columns>id</columns>
            <algorithm>sharding-by-prefixpattern</algorithm>
        </rule>
    </tableRule>
<function name="sharding-by-prefixpattern" class="io.mycat.route.function.PartitionByPrefixPattern">
     <property name="mapFile">partition-prefixpattern.txt</property>
     <property name="prefixLength">0</property>
     <property name="patternValue">96</property>
</function>

partition-prefixpattern.txt配置:

0-32=0
33-64=1
65-96=2

配置说明:

属性 描述
prefixLength 要进行截取的字符串长度
patternValue 取模的基值

#8. 应用指定分片

由运行阶段由应用自主决定路由那个分片,直接根据字符子串(必须是数字)计算分片号:

<tableRule name="sharding-by-substring">
        <rule>
            <columns>id</columns>
            <algorithm>sharding-by-substring</algorithm>
        </rule>
    </tableRule>
<function name="sharding-by-substring" class="io.mycat.route.function.PartitionDirectBySubString">
     <property name="startIndex">0</property>
     <property name="size">2</property>
     <property name="partitionCount">3</property>
     <property name="defaultPartition">0</property>
</function>
属性 描述
startIndex 字符串起始索引
size 字符串长度
partitionCount 分片节点的数量
defaultPartition 默认的分片节点

例:id=02-1000554,在此配置中代表根据id中从startIndex=0,开始,截取size=2位数字即02,02就是获取的节点,如果没有默认分配到defaultPartition

#9. 字符串hash解析分片

截取字符串中的指定位置的子字符串,进行hash算法,算出分片

<tableRule name="sharding-by-stringhash">
        <rule>
            <columns>id</columns>
            <algorithm>sharding-by-stringhash</algorithm>
        </rule>
    </tableRule>
<function name="sharding-by-stringhash" class="io.mycat.route.function.PartitionByString">
     <property name="partitionLength">512</property>
     <property name="partitionCount">3</property>
     <property name="hashSlice">0</property>
</function>
属性 描述
partitionLength hash求模基数;length * count =1024(性能考虑)
hashSlice hash位运算;根据子字符串的hash运算;0代表str.length(),-1代表str.length()-1,大于0只代表数字自身
partitionCount 分片节点的数量
defaultPartition 默认的分片节点

#10. 日期分片

按照日期分片

<tableRule name="sharding-by-date">
        <rule>
            <columns>createTime</columns>
            <algorithm>partbyday</algorithm>
        </rule>
    </tableRule>
    <function name="partbyday"
              class="io.mycat.route.function.PartitionByDate">
        <property name="dateFormat">yyyy-MM-dd</property>
        <property name="sNaturalDay">0</property>
        <property name="sBeginDate">2014-01-01</property>
        <property name="sEndDate">2014-11-31</property>
        <property name="sPartionDay">20</property>
    </function>

该配置含义:2014-01-01开始到2014-11-31结束,每隔20天就进行分片

属性
描述
columns
标识要分片的表字段
algorithm
指定分片函数与function的对应关系
class
指定该分片算法对应的类
dataFormat
日期格式
sBeginDate
开始日期
sEndDate
结束日期,如果配置了结束日期,则代码数据到达这个日期分片后,会重复从开始分片插入
sPartionDay
分区天数,默认为10,从开始日期七,每10天一个分区
注:配置规则的表的dataNode的分片,必须和分片规则数量一致,例如:2020-01-01到2020-12-31每10天一个分片。一共需要37个分片

#11. 日期范围hash算法

其思想和范围取模分片一样,先根据日期进行分片求出分片组,再根据时间hash使得短期内数据分布的更均匀

优点:可以避免扩容时的数据迁移,又可以再一点程度上避免范围分片的热点问题

注:要求日期格式尽量精确,不然达不到局部均匀的目的

<tableRule name="sharding-date-hash">
        <rule>
            <columns>create_time</columns>
            <algorithm>partbyday</algorithm>
        </rule>
    </tableRule>
    <function name="partbyday"
              class="io.mycat.route.function.PartitionByDate">
        <property name="dateFormat">yyyy-MM-dd HH:mm:ss</property>
        <property name="sBeginDate">2022-01-01 00:00:00</property>
        <property name="groupPartionSize">6</property>
        <property name="sPartionDay">10</property>
    </function>
属性 描述
dataFormat 日期格式
sBeginDate 开始日期
groupPartionSize 每组分片数量
sPartionDay 代表多少天为一组