最常见的水平拆分规则
生活随笔
收集整理的這篇文章主要介紹了
最常见的水平拆分规则
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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>partition-hash-int.txt 配置: 10000=0 10010=1 上面columns 標識將要分片的表字段,algorithm 分片函數, 其中分片函數配置中,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算法:
<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天一個分區還有一切特性請看源碼Assert.assertEquals(true, 0 == partition.calculate("2021-01-01")); Assert.assertEquals(true, 0 == partition.calculate("2021-01-10")); Assert.assertEquals(true, 1 == partition.calculate("2021-01-11")); Assert.assertEquals(true, 12 == partition.calculate("2021-05-01"));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 # 64、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阿拉伯數字 * 64、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.編程指定:
<tableRule name="sharding-by-substring"><rule><columns>user_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> <!-- zero-based --><property name="size">2</property><property name="partitionCount">8</property><property name="defaultPartition">0</property></function> 配置說明: 上面columns 標識將要分片的表字段,algorithm 分片函數 此方法為直接根據字符子串(必須是數字)計算分區號(由應用傳遞參數,顯式指定分區號)。 例如id=05-100000002 在此配置中代表根據id中從startIndex=0,開始,截取siz=2位數字即05,05就是獲取的分區,如果沒傳默認分配到defaultPartition9.字符串拆分hash解析:
<tableRule name="sharding-by-stringhash"><rule><columns>user_id</columns><algorithm>sharding-by-stringhash</algorithm></rule></tableRule> <function name="sharding-by-substring" class="io.mycat.route.function.PartitionByString"><property name=length>512</property> <!-- zero-based --><property name="count">2</property><property name="hashSlice">0:2</property></function> 配置說明: 上面columns 標識將要分片的表字段,algorithm 分片函數 函數中length代表字符串hash求模基數,count分區數,hashSlice hash預算位 即根據子字符串 hash運算hashSlice : 0 means str.length(), -1 means str.length()-1/*** "2" -> (0,2)<br/>* "1:2" -> (1,2)<br/>* "1:" -> (1,0)<br/>* "-1:" -> (-1,0)<br/>* ":-1" -> (0,-1)<br/>* ":" -> (0,0)<br/>*/ public class PartitionByStringTest {@Testpublic void test() {PartitionByString rule = new PartitionByString();String idVal=null;rule.setPartitionLength("512");rule.setPartitionCount("2");rule.init();rule.setHashSlice("0:2"); // idVal = "0"; // Assert.assertEquals(true, 0 == rule.calculate(idVal)); // idVal = "45a"; // Assert.assertEquals(true, 1 == rule.calculate(idVal));//last 4rule = new PartitionByString();rule.setPartitionLength("512");rule.setPartitionCount("2");rule.init();//last 4 charactersrule.setHashSlice("-4:0");idVal = "aaaabbb0000";Assert.assertEquals(true, 0 == rule.calculate(idVal));idVal = "aaaabbb2359";Assert.assertEquals(true, 0 == rule.calculate(idVal));}10.一致性hash:
<tableRule name="sharding-by-murmur"><rule><columns>user_id</columns><algorithm>murmur</algorithm></rule></tableRule> <function name="murmur" class="io.mycat.route.function.PartitionByMurmurHash"><property name="seed">0</property><!-- 默認是0--><property name="count">2</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片—><property name="virtualBucketTimes">160</property><!-- 一個實際的數據庫節點被映射為這么多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍--><!--<property name="weightMapFile">weightMapFile</property>節點的權重,沒有指定權重的節點默認是1。以properties文件的格式填寫,以從0開始到count-1的整數值也就是節點索引為key,以節點權重值為值。所有權重值必須是正整數,否則以1代替 --><!--<property name="bucketMapPath">/etc/mycat/bucketMapPath</property>用于測試時觀察各物理節點與虛擬節點的分布情況,如果指定了這個屬性,會把虛擬節點的murmur hash值與物理節點的映射按行輸出到這個文件,沒有默認值,如果不指定,就不會輸出任何東西 --></function>一致性hash預算有效解決了分布式數據的擴容問題,前1-9中id規則都多少存在數據擴容難題,而10規則解決了數據擴容難點總結
以上是生活随笔為你收集整理的最常见的水平拆分规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: expires为session_面试必问
- 下一篇: css 实现一个尖角_一个讲述了 CSS