Skip to content

6 数据分片

6.1 数据分片概述

​ 数据切分是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。

​ 数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点(dataNode)。

6.2 主要切分规则

6.2.1 Hash分区算法

  1. 算法配置

    ​ functionclass属性设置为“hash”或者“com.actiontech.dble.route.function.PartitionByLong"的分区规则应用该算法。具体配置如下:

    xml
    <function name="hashLong" class="hash">
          <property name="partitionCount">C1[,C2, ...Cn]</property>
          <property name="partitionLength">L1[,L2, ...Ln]</property>
    </function>

    partitionCount:指定分区的区间数, 具体为 C1 [+C2 + ... + Cn]. partitionLength:指定各区间长度, 具体区间划分为 [0, L1), [L1, 2L1), ..., [(C1-1)L1, C1L1), [C1L1, C1L1+L2), [C1L1+L2, C1L1+2L2), ... 其中,每一个区间对应一个数据节点。

  2. 配置示例

    • 示例1
    xml
    <property name="partitionCount">2,3</property>
    <property name="partitionLength">100,50</property>

    ​ 将划分如下的分区:[0 , 100) [100, 200) [200,250) [250, 300) [300, 350)

    • 示例2
    xml
    <property name="partitionCount">2</property>
    <property name="partitionLength">1000</property>

    ​ 将划分如下的分区: [0 , 1000) [1000,2000)

​ 根据具体配置, 模的基数M有如下计算公式:C1*L1 + ... + Cn * Ln. 上面的例子中F1 的M值为350,F2的值为2000。 在进行分片查找时, 将分区字段key和M值进行求模运算:value = key mod M 得到的value值再从区间分布中找到自己数据节点的序号。 例如,当配置为F1,key =805 时,value= 105,那么从5个区间内发现对应的数据节点的序号为1(从0开始)。

  1. 注意事项

    a) M不能大于2880;

    b) Cn和Ln的个数必须相等。

    c) 分区字段必须为整型字段。

    d) 当partitionCount为1时,hash分区算法退化为求模算法,M为partitionLength的值。

6.2.2 枚举分区算法

  1. 算法配置

    ​ class属性设置为“enum”或者“com.actiontech.dble.route.function.PartitionByFileMap"的分区规则应用该算法。具体配置如下:

    xml
    <function name="enum" class="enum">
           <property name="mapFile">partition.txt</property>
           <property name="defaultNode">0</property>
           <property name="type">0</property>
    </function>

    mapFile:指定配置文件名。其格式将在下面做详细说明。

    defaultNode:指定默认节点号。默认值为-1, 不指定默认节点。 type:指定配置文件中key的类型。0:整型; 其它:字符串。

    ​ 配置文件格式如下:a. type值为0时,

    properties
    #comment 
    //comment this line will be skiped
     int1=node0 
    int2=node1 
    ...

    b. type值为非0时,

    properties
    #comment   //comment this line will be skiped 
    string1=node0 
    string2=node1

    ​ 在进行分片查找时,分片字段的枚举值对应的数据节点既是目的节点。如果不能在配置映射中找到枚举值对应的数据节点:如果配置了defaultNode,则defaultNode既是目的数据节点, 否则出错。

  2. 注意事项

    a) 不包含“=”的行将被跳过.

    b) nodex为数据节点索引号。

    c) 重复的枚举值的分区数据节点以最后一个配置为准。

    d) 分片字段为该枚举类型。

6.2.3 范围分区算法

  1. 算法配置

    ​ class属性设置为“numberrange”或者“com.actiontech.dble.route.function.AutoPartitionByLong"的分区规则应用该算法。具体配置如下:

    xml
    <function name="rangeLong" class="numberrange">
           <property name="mapFile">partition.txt</property>
           <property name="defaultNode">0</property>
    </function>

    mapFile:指定配置文件名。其格式将在下面做详细说明。

    defaultNode:指定默认节点号。默认值为-1, 不指定默认节点。

    ​ 配置文件格式如下

    properties
    #comment   //comment this line will be skiped 
    start1-end1=node1 
    start2-end2=node2  
    ...

    ​ 该分区算法相当于定义了区间序列 [start1, end1], [start2, end2], ... 每一个区间对应一个数据节点。 在进行分片查找时,分片字段的值落在的区间对应的数据节点即是目的节点。 如果不能在配置映射中找到分片字段的值所落的区间时,分两种情况:1.配置了defaultNode,则defaultNode是目的数据节点;2.没配defaultNode,出错。

  2. 注意事项

    a) 不包含“=”的行将被跳过。

    b) nodex为数据节点索引号。

    c) 如果区间存在重合, 在对重合部分的分片字段值进行分片查找时在配置文件中最先定义的区间对应的数据节点为目的节点。

    d) 分片字段为整型。

6.2.4 日期分区算法

  1. 算法配置

    ​ class属性设置为“date”或者“com.actiontech.dble.route.function.PartitionByDate"的分区规则应用该算法。具体配置如下:

    xml
    <function name="partbydate" class="date">
           <property name="dateFormat">yyyy-MM-dd</property>
           <property name="sBeginDate">2015-01-01</property>
           [<property name="sEndDate">2015-01-31</property>]
           <property name="sPartionDay">10</property>
           <property name="defaultNode">0</property>
    </function>

    dateFormat:指定日期的格式。

    sBeginDate:指定日期的开始时间。

    sEndDate:指定日期的结束时间。该性质可以不配置或配置为空("")。

    sPartionDay:指定分区的间隔,单位是天。

    defaultNode:指定默认节点号。默认值为-1, 不指定默认节点。

    ​ 该算法有两种工作模式: 模式1:不配置sEndDate或者将sEndDate配置为"" 在这种模式下, 该算法将时间以sBeginDate为开始, 以sPartionDay为间隔,进行区间划分, 每个区间对应一个数据节点。 在进行区间查找时,分区字段值落在的区间对应的数据节点既是目的数据节点。如果分区字段值小于sBeginDate:如果配置了defaultNode,则defaultNode既是目的数据节点, 否则出错。 模式2:配置sEndDate且不为"" 在这种模式下, 该算法将时间以sBeginDate为开始, 以sPartionDay为间隔,以sEndDate为终点, 进行区间划分,划分为N个区间, 每个区间对应一个数据节点。 在进行区间查找时: 如果分区字段值小于等于sEndDate,则计算过程和结果等同于模式1。如果分区字段值大sEndDate,则分片查找公式为:index=((key - sBeginDate)/sPartionDay)%N, 其中key为分片字段值, index为映射到的数据节点索引。这等同于一个环形映射。

  2. 注意事项

    a) 分片字段必须是符合dateFormat的日期字符串。

    b) 区间划分不以日历时间为准,无法对应到日历时间。内部进行区间划分时,会将sPartionDay转化为以86400000毫秒为一天进行运算。

    c) 在模式2的情况下, 如果(sEndDate- sBeginDate)不是sPartionDay的整数倍,则索引号为0的数据节点承载更多的数据。

6.3 自定义切分规则

​ 在LIBRA中定义了分片算法的接口RuleAlgorithm,开发者只需要实现该接口完成算法的编写即可,按如下配置即可完成对自定义算法的使用。

​ 在rule.xml文件中配置切分算法

xml
<tableRule name="calculate">
    <rule>
<!—切分列,只能是一列 -->
        <columns>id</columns>
<!-- 路由函数定义 -->
        <algorithm>func0</algorithm>
    </rule>
</tableRule>

<!-- 路由函数定义 -->
<function name="func0" 
<!—切分算法 -->
class="com.actiontech.dble.route.function.NewPartition">
<!—切分算法需要的参数 -->
    <property name="parameter1">value</property>
    <property name="parameter2">value</property>
    ...
</function>

​ 在schema.xml文件中使用路由规则

xml
<schema name="TestDb1" checkSQLschema="false" dbType="oracle">
     <table name="table1" dataNode="dn1,dn2" rule="func0" >calculate</table>
</schema>