分片規則概述:node
在數據切分處理中,特別是水平切分中,中間件最終要的兩個處理過程就是數據的切分、數據的聚合。選擇合適的切分規則,相當重要,由於它決定了後續數據聚合的難易程度,甚至能夠避免跨庫的數據聚合處理。python
rule.xml配置文件
rule.xml 裏面就定義了咱們對錶進行拆分所涉及到的規則定義。
咱們能夠靈活的對錶使用不一樣的分片算法,或者對錶使用相同的算法但具體的參數不一樣。這個文件裏面主要有 tableRule 和 function 這兩個標籤。在具體使用過程當中能夠按照需求添加 tableRule 和 function。算法
tableRule 標籤
這個標籤訂義表規則。在 schema.xml配置中使用。數據庫
<tableRule name="rule1"> <rule> <columns>id</columns> <algorithm>func1</algorithm> </rule> </tableRule>
name 屬性
指定惟一的名字,用於標識不一樣的表規則。分佈式rule 標籤
指定對物理表中的哪一列進行拆分和使用什麼路由算法。函數columns 標籤
指定要拆分的列名字。測試algorithm 標籤
使用 function 標籤中的 name 屬性。鏈接表規則和具體路由算法。固然,多個表規則能夠鏈接到同一個路由算法上。table 標籤內使用。讓邏輯表使用這個規則進行分片。this
function 標籤
這個標籤訂義表規則的具體算法。spa
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"> <property name="mapFile">partition-hash-int.txt</property> </function>
name 屬性
指定算法的名字。
class 屬性
制定路由算法具體的類名字。日誌property 標籤
具體算法須要用到的一些屬性。
#####################################
下面將介紹 Mycat 目前已有的分片規則,每種規則都有特定的場景,分析每種規則去選擇合適的應用到項目中。
<一>分片枚舉:
算法說明:
經過在配置文件中配置的可能的枚舉 id,本身配置分片,本規則適用於特定的場景,好比有些業務須要按照省
份或區縣來作保存,而全國省份區縣是固定的,這類業務使用本條規則
<tableRule name="sharding-by-intfile"> <rule> <columns>user_id</columns> <algorithm>hash-int</algorithm> </rule> </tableRule> <function name="hash-int" class="org.opencloudb.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 DEFAULT_NODE=1
分片函數配置中:
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
<二>固定分片 hash 算法:
算法說明:
本條規則相似於十進制的求模運算,區別在因而二進制的操做,是取 id 的二進制低 10 位(二進制高位、低位說明:左邊爲高位,右邊爲低位),即 id 二進制&1111111111;也就是說從右邊數取10位。
此算法的優勢在於若是按照十進制取模運算,在連續插入 1-10 時候 1-10 會被分到 1-10 個分片,增大了插入的事務控制難度,而此算法根據二進制則可能會分到連續的分片,減小插入事務事務控制難度。
<tableRule name="rule1"> <rule> <columns>user_id</columns> <algorithm>func1</algorithm> </rule> </tableRule> <function name="func1" class="org.opencloudb.route.function.PartitionByLong"> <property name="partitionCount">2,1</property> <property name="partitionLength">256,512</property> </function>
分片函數配置中:
partitionCount屬性:
分片個數列表。
partitionLength屬性:
分片範圍列表。
分區長度:默認爲最大 2^n=1024 ,即最大支持 1024 分區;意思就是分片個數 * 分片範圍 = 1024。
用法例子:
本例的分區策略:但願將數據水平分紅 3 份,前兩份各佔 25%,第三份佔 50%。(故本例非均勻分區)
|<——————————1024———————————>|
|<——256—>|<——256——>|<————512————->|
| partition0 | partition1 | partition2 |
| 共 2 份,故 count[0]=2 | 共 1 份,故 count[1]=1 |
若是平均分紅4份怎麼分?
|<——256—>|<——256——>|<——256—>|<——256——>|
<function name="func1" class="org.opencloudb.route.function.PartitionByLong"> <property name="partitionCount">4</property> <property name="partitionLength">256</property> </function>
<三>取模
算法說明:
此種規則很是明確即根據 id 進行十進制求模預算,相比固定分片 hash算法,此種在批量插入時可能存在批量插入單事務插入多數據分片,增大事務一致性難度。
<tableRule name="mod-long"> <rule> <columns>user_id</columns> <algorithm>mod-long</algorithm> </rule> </tableRule> <function name="mod-long" class="org.opencloudb.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">3</property> </function>
<四>範圍約定
算法說明:
此分片適用於,提早規劃好分片字段某個範圍屬於哪一個分片,
start <= range <= end.
range start-end ,data node index
K=1000,M=10000.
<tableRule name="auto-sharding-long"> <rule> <columns>user_id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule> <function name="rang-long" class="org.opencloudb.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> <property name="defaultNode">0</property> </function> ##配置文件: autopartition-long.txt K=1000,M=10000. 0-500M=0 500M-1000M=1 1000M-1500M=2 或 0-10000000=0 10000001-20000000=1
分片函數配置中:
mapFile屬性:
表明配置文件路徑。
defaultNode屬性:
超過範圍後的默認節點。
全部的節點配置都是從 0 開始,及 0 表明節點 1,此配置很是簡單,即預先制定可能的 id 範圍到某個分片。
<五>取模範圍約束
算法說明:
此種規則是取模運算與範圍約束的結合,主要爲了後續數據遷移作準備,便可以自主決定取模後數據的節點分佈。
<tableRule name="sharding-by-pattern"> <rule> <columns>user_id</columns> <algorithm>sharding-by-pattern</algorithm> </rule> </tableRule> <function name="sharding-by-pattern" class="org.opencloudb.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
分片函數配置中:
patternValue屬性:
即求模基數。
defaoultNode屬性:
默認節點。
mapFile屬性:
配置文件路徑
配置文件中,1-32 即表明 id%256 後分布的範圍,若是在 1-32 則在分區 1,其餘類推,若是 id 非數據,則會分配在 defaoultNode 默認節點。
<六>截取數字作 hash 求模範圍約束
算法說明:
此種規則相似於取模範圍約束,此規則支持數據、符號、字母取模。
<tableRule name="sharding-by-prefixpattern"> <rule> <columns>user_id</columns> <algorithm>sharding-by-prefixpattern</algorithm> </rule> </tableRule> <function name="sharding-by-pattern" class="org.opencloudb.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 # 8-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
分片函數配置中:
patternValue屬性:
求模基數。
prefixLength屬性:
ASCII 截取的位數。
mapFile屬性:
配置文件路徑
配置文件中,1-32 即表明 id%256 後分布的範圍,若是在 1-32 則在分區 1,其餘類推此種方式相似方式 取模範圍約束 只不過採起的是將分區列中獲取前 prefixLength 位列全部 ASCII 碼的和進行求模sum%patternValue ;獲取的值,在範圍內的分片數。
<七>範圍求模分片
算法說明:
先進行範圍分片,計算出分片組,組內再求模;
優勢能夠避免擴容時的數據遷移,又能夠必定程度上避免範圍分片的熱點問題。
綜合了範圍分片和求模分片的優勢,分片組內使用求模能夠保證組內數據比較均勻,分片組之間是範圍分片能夠兼顧範圍查詢。最好事先規劃好分片的數量,數據擴容時按分片組擴容,則原有分片組的數據不須要遷移。因爲分片組內數據比較均勻,因此分片組內能夠避免熱點數據問題。
<tableRule name="auto-sharding-rang-mod"> <rule> <columns>id</columns> <algorithm>rang-mod</algorithm> </rule> </tableRule> <function name="rang-mod" class="org.opencloudb.route.function.PartitionByRangeMod"> <property name="mapFile">partition-range-mod.txt</property> <property name="defaultNode">21</property> </function> ##配置文件: partition-range-mod.txt range start-end ,data node group size ##如下配置一個範圍表明一個分片組,=號後面的數字表明該分片組所擁有的分片的數量。 0-200M=5 #表明有 5 個分片節點 200M1-400M=1 400M1-600M=4 600M1-800M=4 800M1-1000M=6
分片函數配置中:
mapFile屬性:
表明配置文件路徑。
defaultNode屬性:
超過範圍後的默認節點順序號,節點從 0 開始。
<八>截取數字 hash 解析
算法說明:
此規則是截取字符串中的 int 數值 hash 分片。
<tableRule name="sharding-by-stringhash"> <rule> <columns>user_id</columns> <algorithm>sharding-by-stringhash</algorithm> </rule> </tableRule> <function name="sharding-by-stringhash" class="org.opencloudb.route.function.PartitionByString"> <property name="partitionLength">512</property><!-- zero-based --> <property name="partitionCount">2</property> <property name="hashSlice">0:2</property> </function>
分片函數配置中:
partitionLength屬性:
表明字符串 hash 求模基數。
partitionCount屬性:
分區數。
hashSlice屬性:
hash 預算位,即根據子字符串中 int 值 hash 運算
hashSlice : 0 means str.length(), -1 means str.length()-1
/**
* 「2」 -> (0,2)
* 「1:2」 -> (1,2)
* 「1:」 -> (1,0)
* 「-1:」 -> (-1,0)
* 「:-1」 -> (0,-1)
* 「:」 -> (0,0)
*/
<九>按日期(天)分片
算法說明:
此規則爲按天分片。
<tableRule name="sharding-by-date"> <rule> <columns>create_time</columns> <algorithm>sharding-by-date</algorithm> </rule> </tableRule> <function name="sharding-by-date" class="org.opencloudb.route.function.PartitionByDate"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2014-01-01</property> <property name="sEndDate">2014-01-02</property> <property name="sPartionDay">10</property> </function>
分片函數配置中:
dateFormat屬性:日期格式
sBeginDate屬性:開始日期
sEndDate屬性:結束日期
sPartionDay屬性:分區天數,即默認從開始日期算起,分隔 10 天一個分區。
若是配置了 sEndDate 則表明數據達到了這個日期的分片後後循環從開始分片插入。
<十>日期範圍 hash 分片
算法說明:
思想與範圍求模一致,當因爲日期在取模會有數據集中問題,因此改爲 hash 方法。先根據日期分組,再根據時間 hash 使得短時間內數據分佈的更均勻。
優勢能夠避免擴容時的數據遷移,又能夠必定程度上避免範圍分片的熱點問題要求日期格式儘可能精確些,否則達不到局部均勻的目的。
< tableRule name="rangeDateHash"> <rule> <columns>col_date</columns> <algorithm>range-date-hash</algorithm> </rule> </tableRule> <function name="range-date-hash" class="org.opencloudb.route.function.PartitionByRangeDateHash"> <property name="sBeginDate">2014-01-01 00:00:00</property> <property name="sPartionDay">3</property> <property name="dateFormat">yyyy-MM-dd HH:mm:ss</property> <property name="groupPartionSize">6</property> </function>
分片函數配置中:
sPartionDay屬性:
表明多少天分一個分片
groupPartionSize屬性:
表明分片組的大小。
<十一>天然月分片
算法說明:
按月份列分區 ,每一個天然月一個分片,格式 between 操做解析的範例。
<tableRule name="sharding-by-month"> <rule> <columns>create_time</columns> <algorithm>sharding-by-month</algorithm> </rule> </tableRule> <function name="sharding-by-month" class="org.opencloudb.route.function.PartitionByMonth"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2014-01-01</property> </function>
分片函數配置中:
dateFormat : 日期字符串格式
sBeginDate : 開始日期。
<十二>按單月小時拆分
算法說明:
此規則是單月內按照小時拆分,最小粒度是小時,能夠一天最多 24 個分片,最少 1 個分片,一個月完後下月從頭開始循環。每月月尾,須要手工清理數據。
<tableRule name="sharding-by-hour"> <rule> <columns>create_time</columns> <algorithm>sharding-by-hour</algorithm> </rule> </tableRule> <function name="sharding-by-hour" class="org.opencloudb.route.function.LatestMonthPartion"> <property name="splitOneDay">24</property> </function>
分片函數配置中:
splitOneDay : 一天切分的分片數。
<十三>冷熱數據分片
算法說明:
根據日期查詢日誌數據 冷熱數據分佈 ,最近 n 個月的到實時交易庫查詢,超過 n 個月的按照 m 天分片。
<tableRule name="sharding-by-date"> <rule> <columns>create_time</columns> <algorithm>sharding-by-hotdate</algorithm> </rule> </tableRule> <function name="sharding-by-hotdate" class="org.opencloudb.route.function.PartitionByHotDate"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sLastDay">10</property> <property name="sPartionDay">30</property> </function>
分片函數配置中:
sPartionDay屬性:表明多少天分一個分片
sLastDay屬性:表明超過多少天開始按照sPartionDay分片。
<十四>一致性 hash
算法說明:
一致性 hash 預算有效解決了分佈式數據的擴容問題。
<tableRule name="sharding-by-murmur"> <rule> <columns>user_id</columns> <algorithm>murmur</algorithm> </rule> </tableRule> <function name="murmur" class="org.opencloudb.route.function.PartitionByMurmurHash"> <property name="seed">0</property> <property name="count">2</property> <property name="virtualBucketTimes">160</property> <property name="weightMapFile">weightMapFile</property> <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> </function>
分片函數配置中:
seed屬性: 默認是 0
count屬性:
要分片的數據庫節點數量,必須指定,不然無法分片。
virtualBucketTimes屬性:
一個實際的數據庫節點被映射爲這麼多虛擬節點,默認是 160 倍,也就是虛擬節點數是物理節點數的 160 倍。
weightMapFile屬性:
節點的權重,沒有指定權重的節點默認是 1。以 properties 文件的格式填寫,以從 0 開始到 count-1 的整數值也就是節點索引爲 key,以節點權重值爲值。全部權重值必須是正整數,不然以 1 代替。
bucketMapPath屬性:
用於測試時觀察各物理節點與虛擬節點的分佈狀況,若是指定了這個屬性,會把虛擬節點的 murmur hash 值與物理節點的映射按行輸出到這個文件,沒有默認值,若是不指定,就不會輸出任何東西。
<十五>應用指定
算法說明:
此規則是在運行階段有應用自主決定路由到那個分片。
此方法爲直接根據字符子串(必須是數字)計算分區號(由應用傳遞參數,顯式指定分區號)。
<tableRule name="sharding-by-substring"> <rule> <columns>user_id</columns> <algorithm>sharding-by-substring</algorithm> </rule> </tableRule> <function name="sharding-by-substring" class="org.opencloudb.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>
實例說明: id=05-100000002 在此配置中表明根據 id 中從 startIndex=0,開始,截取 siz=2 位數字即 05,05 就是獲取的分區,若是沒傳默認分配到 defaultPartition