MyCat分片規則--筆記(二)

概述node

  myCat實現分庫分表的策略,對數據量的處理帶來很大的便利,這裏主要整理下MyCat的使用以及經常使用路由算法,針對MyCat裏面的事務、集羣后續再作整理;另外內容整理,難免會參考技術大牛的博客,內容雷同,實屬正常;基於業務區分數據源,主要爲了實現以下的數據庫mysql

 

常規使用算法

配置schema.xml  在同一個mysql數據庫中,建立了三個數據庫 testdb1,testdb2,testdb3。並在每一個庫中都建立了user表
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
 
   <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100」  >
       <!——指定rule 分片規則-->
      <table name="user" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile" />
   </schema>
 
    <dataNode name="dn1" dataHost="host" database="testdb1" />
    <dataNode name="dn2" dataHost="host" database="testdb2" />
    <dataNode name="dn3" dataHost="host" database="testdb3" />
 
    <dataHost name="host" maxCon="1000" minCon="10" balance="0"
       writeType="0" dbType="mysql" dbDriver="native">
       <heartbeat>select 1</heartbeat>
       <writeHost host="hostM1" url="localhost:3306" user="root" password="123" />
    </dataHost>
 
</mycat:schema>
View Code
配置server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
     <system>
          <property name="defaultSqlParser">druidparser</property>
     </system>
     <user name="mycat">
          <property name="password">mycat</property>
          <property name="schemas">testdb</property>
     </user>
</mycat:server>
View Code
配置rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/「>
    <tableRule name="sharding-by-intfile">
          <rule>
               <columns>sharding_id</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>
     </function>
</mycat:rule>
View Code

經常使用的分片規則sql

1、枚舉法數據庫

<tableRule name="sharding-by-intfile">
    <rule>
      <columns>user_id</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="type">0</property>
    <property name="defaultNode">0</property>
  </function>

這個是針對Int類型的枚舉算法,若是是標識字符串枚舉,可將function作以下調整: <property name="type">1</property>數組

partition-hash-int.txt 文件配置:框架

10000=0ide

10010=1函數

上面columns 標識將要分片的表字段,algorithm 分片函數,ui

其中分片函數配置中,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    

*/

2、固定分片hash算法(整體長度1024)

<tableRule name="rule1">
    <rule>
      <columns>user_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>

配置說明:

上面columns 標識將要分片的表字段,algorithm 分片函數,

partitionCount 分片個數列表,partitionLength 分片範圍列表

分區長度:默認爲最大2^n=1024 ,即最大支持1024分區

約束 :

count,length兩個數組的長度必須是一致的。

1024 = sum((count[i]*length[i])). count和length兩個向量的點積恆等於1024

用法例子:

@Test

public void testPartition() {

    // 本例的分區策略:但願將數據水平分紅3份,前兩份各佔25%,第三份佔50%。(故本例非均勻分區)

    // |<---------------------1024------------------------>|

    // |<----256--->|<----256--->|<----------512---------->|

    // | partition0 | partition1 | partition2 |

    // | 共2份,故count[0]=2 | 共1份,故count[1]=1 |

    int[] count = new int[] { 2, 1 };

    int[] length = new int[] { 256, 512 };

    PartitionUtil pu = new PartitionUtil(count, length);

    // 下面代碼演示分別以offerId字段或memberId字段根據上述分區策略拆分的分配結果

    int DEFAULT_STR_HEAD_LEN = 8; // cobar默認會配置爲此值

    long offerId = 12345;

    String memberId = "qiushuo";

    // 若根據offerId分配,partNo1將等於0,即按照上述分區策略,offerId爲12345時將會被分配到partition0中

    int partNo1 = pu.partition(offerId);

    // 若根據memberId分配,partNo2將等於2,即按照上述分區策略,memberId爲qiushuo時將會被分到partition2中

    int partNo2 = pu.partition(memberId, 0, DEFAULT_STR_HEAD_LEN);

    Assert.assertEquals(0, partNo1);

    Assert.assertEquals(2, partNo2);

}

若是須要平均分配設置:平均分爲4分片,partitionCount*partitionLength=1024

<function name="func1" class="org.opencloudb.route.function.PartitionByLong">

    <property name="partitionCount">4</property>

    <property name="partitionLength">256</property>

  </function>

3、範圍約定

<tableRule name="auto-sharding-long">
    <rule>
      <columns>user_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>

# range start-end ,data node index

# K=1000,M=10000.

0-500M=0

500M-1000M=1

1000M-1500M=2

0-10000000=0

10000001-20000000=1

配置說明:

上面columns 標識將要分片的表字段,algorithm 分片函數,

rang-long 函數中mapFile表明配置文件路徑

全部的節點配置都是從0開始,及0表明節點1,此配置很是簡單,即預先制定可能的id範圍到某個分片

4、求模法

<tableRule name="mod-long">
    <rule>
      <columns>user_id</columns>
      <algorithm>mod-long</algorithm>
    </rule>
  </tableRule>
  <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
   <!-- how many data nodes  -->
    <property name="count">3</property>
  </function>

配置說明:

上面columns 標識將要分片的表字段,algorithm 分片函數,

此種配置很是明確即根據id與count(你的結點數)進行求模預算,相比方式1,此種在批量插入時須要切換數據源,id不連續

 5、日期列分區法

<tableRule name="sharding-by-date">
      <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-date</algorithm>
      </rule>
</tableRule> 
<function name="sharding-by-date" class="io.mycat.route.function..PartitionByDate">
   <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2014-01-01</property>
    <property name="sPartionDay">10</property>
</function>

配置說明:

上面columns 標識將要分片的表字段,algorithm 分片函數,

配置中配置了開始日期,分區天數,即默認從開始日期算起,分隔10天一個分區

6、通配取模

<tableRule name="sharding-by-pattern">
      <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-pattern</algorithm>
      </rule>
   </tableRule>
<function name="sharding-by-pattern" class="io.mycat.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

配置說明:

上面columns 標識將要分片的表字段,algorithm 分片函數,patternValue 即求模基數,defaoultNode 默認節點,若是不配置了默認,則默認是0即第一個結點

mapFile 配置文件路徑

配置文件中,1-32 即表明id%256後分布的範圍,若是在1-32則在分區1,其餘類推,若是id非數字數據,則會分配在defaoultNode 默認節點

String idVal = "0";

Assert.assertEquals(true, 7 == autoPartition.calculate(idVal));

idVal = "45a";

Assert.assertEquals(true, 2 == autoPartition.calculate(idVal));

7、ASCII碼求模通配

<tableRule name="sharding-by-prefixpattern">
      <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-prefixpattern</algorithm>
      </rule>
   </tableRule>
<function name="sharding-by-pattern" class="io.mycat.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

# 48-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

配置說明:

上面columns 標識將要分片的表字段,algorithm 分片函數,patternValue 即求模基數,prefixLength ASCII 截取的位數

mapFile 配置文件路徑

配置文件中,1-32 即表明id%256後分布的範圍,若是在1-32則在分區1,其餘類推 

此種方式相似方式6只不過採起的是將列種獲取前prefixLength位列全部ASCII碼的和進行求模sum%patternValue ,獲取的值,在通配範圍內的

即 分片數,

/**

* ASCII編碼:

* 48-57=0-9阿拉伯數字

* 6四、65-90=@、A-Z

* 97-122=a-z

*/

如 

String idVal="gf89f9a";

Assert.assertEquals(true, 0==autoPartition.calculate(idVal));

idVal="8df99a";

Assert.assertEquals(true, 4==autoPartition.calculate(idVal));

idVal="8dhdf99a";

Assert.assertEquals(true, 3==autoPartition.calculate(idVal));

8、其餘分區:按月(12個月)和天分區(24區)

<function name="latestMonth"
        class="io.mycat.route.function.LatestMonthPartion">
        <property name="splitOneDay">24</property>
    </function>
    <function name="partbymonth"
        class="io.mycat.route.function.PartitionByMonth">
        <property name="dateFormat">yyyy-MM-dd</property>
        <property name="sBeginDate">2015-01-01</property>
    </function>

嘗試MyCat總結

一、MyCat宣稱對Oracle數據庫進行支持,可是也僅僅侷限於常規的語句,對MyCat的連接驅動仍是要mysql,一些常規的登陸,轉到Oracle語句就報錯;若是想基於MyCat作分庫分表機制,仍是建議DB選擇:mySQL

二、MyCat配置完整以後,數據表對接,都是小寫的;若是應用框架(Spring-Oracle)採用Table名稱大寫查詢操做,MyCat是無法予以支持;若是是(Spring-Mysql)框架模式,到時能夠修改Mysql配置,不區分大寫小屬性完成;

相關文章
相關標籤/搜索