分佈式 | MyCat如何遷移到DBLE之分片算法對比解析:stringhash分片

原創做者: 鍾悅算法


關於做者數組

鍾 悅  -  資深DBLE用戶安全

某宇宙行資深架構師,在大型重點項目中使用 DBLE。架構

常年與 MySQL 糾纏不清,常常運用技術處理大企業病的技術or非技術問題的一個挨踢從業者。運維

 

當分片索引不是純整型的字符串時,只接受整型的內置 hash 算法是沒法使用的。爲此,stringhash 按照用戶定義的起點和終點去截取分片索引字段中的部分字符,根據當中每一個字符的二進制 unicode 值換算出一個長整型數值,而後就直接調用內置 hash 算法求解分片路由:先求模獲得邏輯分片號,再根據邏輯分片號直接映射到物理分片。code

  • 用戶須要在 rule.xml 中定義 partitionLength[] 和 partitionCount[] 兩個數組和 hashSlice 二元組。xml

  • 在 DBLE 的啓動階段,點乘兩個數組獲得模數,也是邏輯分片的數量blog

  • 而且根據兩個數組的叉乘,獲得各個邏輯分片到物理分片的映射表(物理分片數量由 partitionCount[] 數組的元素值之和)繼承

  • 此外根據 hashSlice 二元組,約定把分片索引值中的第 4 字符到第 5 字符(字符串以 0 開始編號,編號 3 到編號 4 等於第 4 字符到第 5 字符)字符串用於 「字符串->整型」的轉換索引

  • 在 DBLE 的運行過程當中,用戶訪問使用這個算法的表時,WHERE 子句中的分片索引值會被提取出來,取當中的第 4 個字符到第 5 字符,送入下一步

  • 設置一個初始值爲 0 的累計值,逐個取字符,把累計值乘以 31,再把這個字符的 unicode 值當成長整型加入到累計值中,如此類推直至處理完截取出來的全部字符,此時的累計值就可以表明用戶的分片索引值,完成了 「字符串->整型」 的轉換

  • 對上一步的累計值進行求模,獲得邏輯分片號

  • 再根據邏輯分片號,查映射表,直接獲得物理分片號

 

與MyCat的相似分片算法對比

兩種算法在string轉化爲int以後,和 hash 分區算法相同,區別也繼承了 hash 算法的區別。

 

開發注意點

【分片索引】1. 必須是字符串

【分片索引】2. 最大物理分片配置方法是,讓 partitionCount[] 數組和等於 2880

例如:

<property name="partitionLength">1</property>
<property name="partitionCount">2880</property>

<property name="partitionLength">1,1</property>
<property name="partitionCount">1440,1440</property>

【分片索引】3. 最小物理分片配置方法是,讓 partitionCount[] 數組和等於 1

例如

<property name="partitionLength">2880</property>
<property name="partitionCount">1</property>

【分片索引】4. partitionLength 和 partitionCount 被當作兩個逗號分隔的一維數組,它們之間的點乘必須在 [1, 2880] 範圍內

【分片索引】5. partitionLength 和 partitionCount 的配置對順序敏感

<property name="partitionLength">512,256</property>
<property name="partitionCount">1,2</property>

<property name="partitionLength">256,512</property>
<property name="partitionCount">2,1</property>

是不一樣的分片結果

【分片索引】6. 分片索引字段長度小於用戶指定的截取長度時,截取長度會安全減小到符合分片索引字段長度

【數據分佈】1. 分片索引字段截取越長則越有利於數據均勻分佈

【數據分佈】2. 分片索引字段的內容重複率越低則越有利於數據均勻分佈

 

運維注意點

【擴容】1. 預先過量分片,而且不改變 partitionCount 和 partitionLength 點乘結果,也不改變截取設置 hashSlice 時,能夠避免數據再平衡,只需進行涉及數據的遷移

【擴容】2. 若須要改變 partitionCount 和 partitionLength 點乘結果或改變截取設置 hashSlice 時,須要數據再平衡

【縮容】1. 預先過量分片,而且不改變 partitionCount 和 partitionLength 點乘結果,也不改變截取設置 hashSlice 時,能夠避免數據再平衡,只需進行涉及數據的遷移

【縮容】2. 若須要改變 partitionCount 和 partitionLength 點乘結果或改變截取設置 hashSlice 時,須要數據再平衡

 

配置注意點

【配置項】1. 在 rule.xml 中,可配置項爲 <property name="partitionLength">  、<property name="partitionCount"><property name="hashSlice">

【配置項】2.在 rule.xml 中配置 <property name="partitionLength"> 標籤

內容形式爲:<物理分片持有的虛擬分片數>[,<物理分片持有的虛擬分片數>,...<物理分片持有的虛擬分片數>]

物理分片持有的虛擬分片數必須是整型,物理分片持有的虛擬分片數從左到右與同順序的物理分片數對應,partitionLength 和partitionCount 的點乘結果必須在 [1, 2880] 範圍內

【配置項】3. 在 rule.xml 中配置 <property name="partitionCount"> 標籤 內容形式爲:<物理分片數>[,<物理分片數>,...<物理分片數>]

其中物理分片數必須是整型,物理分片數按從左到右的順序與同順序的物理分片持有的虛擬分片數對應,物理分片的編號從左到右連續遞進,partitionLength 和 partitionCount 的點乘結果必須在 [1, 2880] 範圍內

【配置項】4. partitionLength 和 partitionCount 的語義是:持有partitionLength[i] 個虛擬分片的物理分片有 partitionCount[i] 個

例如

<property name="partitionLength">512,256</property>
<property name="partitionCount">1,2</property>

語義是持有 512 個邏輯分片的物理分片有 1 個,緊隨其後,持有 256 個邏輯分片的物理分片有 2 個

【配置項】5.partitionLength 和 partitionCount 都對書寫順序敏感,

例如

<property name="partitionLength">512,256</property>
<property name="partitionCount">1,2</property>

分片結果是第一個物理分片持有頭512個邏輯分片,第二個物理分片持有緊接着的256個邏輯分片,第三個物理分片持有最後256個邏輯分片,相對的

<property name="partitionLength">256,512</property>
<property name="partitionCount">2,1</property>

分片結果則是第一個物理分片持有頭 256 個邏輯分片,第二個物理分片持有緊接着的 256 個邏輯分片,第三個物理分片持有最後 512 個邏輯分片

【配置項】6.partitionLength[] 的元素所有爲 1 時,這時候partitionCount 數組和等於 partitionLength 和 partitionCount 的點乘,物理分片和邏輯分片就會一一對應,該分片算法等效於直接取餘

【配置項】7.在 rule.xml 中配置標籤,從分片索引字段的第幾個字符開始截取到第幾個字符:

  • 若但願從首字符開始截取 k 個字符( k 爲正整數),配置的內容形式能夠爲「 0 : k 」、「 k 」或「 : k 」;

  • 若但願從末字符開始截取 k 個字符( k 爲正整數),則配置的內容形式能夠爲「 -k : 0 」、「 -k 」或「 -k : 」;

  • 若但願從頭第 m 個字符起算截取 n 個字符( m 和 n 都是正整數),則先計算出 i = m - 1 和 j = i + n - 1,配置的內容形式爲「 i : j 」;

  • 若但願從尾第 m 個字符起算截取從尾算起的 n 個字符( m 和 n 都是正整數),則先計算出 i = -m + n - 1,配置的內容形式能夠爲「 -m : i 」;

  • 若但願不截取,則配置的內容形式能夠爲「 0 : 0 」、「 0 : 」、「 : 0 」或 「 : 」

相關文章
相關標籤/搜索