概述node
myCat實現分庫分表的策略,對數據量的處理帶來很大的便利,這裏主要整理下MyCat的使用以及經常使用路由算法,針對MyCat裏面的事務、集羣后續再作整理;另外內容整理,難免會參考技術大牛的博客,內容雷同,實屬正常;基於業務區分數據源,主要爲了實現以下的數據庫mysql
常規使用算法
<?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>
<?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>
<?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>
經常使用的分片規則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配置,不區分大寫小屬性完成;