當(dāng)分片索引不是純整型的字符串時,只接受整型的內(nèi)置hash算法是無法使用的。為此,stringhash按照用戶定義的起點和終點去截取分片索引字段中的部分字符,根據(jù)當(dāng)中每個字符的二進制unicode值換算出一個長整型數(shù)值,然后就直接調(diào)用內(nèi)置hash算法求解分片路由:先求模得到邏輯分片號,再根據(jù)邏輯分片號直接映射到物理分片。建議在閱讀本分片算法前,先閱讀hash算法章節(jié)。

PartitionByString工作示意圖
- 用戶需要在rule.xml中定義partitionLength[]和partitionCount[]兩個數(shù)組和hashSlice二元組。
- 在DBLE的啟動階段,點乘兩個數(shù)組得到模數(shù),也是邏輯分片的數(shù)量
- 并且根據(jù)兩個數(shù)組的叉乘,得到各個邏輯分片到物理分片的映射表(物理分片數(shù)量由partitionCount[]數(shù)組的元素值之和)
- 此外根據(jù)hashSlice二元組,約定把分片索引值中的第4字符到第5字符(字符串以0開始編號,編號3到編號4等于第4字符到第5字符)字符串用于“字符串->整型”轉(zhuǎn)換
- 在DBLE的運行過程中,用戶訪問使用這個算法的表時,WHERE子句中的分片索引值會被提取出來,取當(dāng)中的第4個字符到第5字符,送入下一步
- 設(shè)置一個初始值為0的累計值,逐個取字符,把累計值乘以31,再把這個字符的unicode值當(dāng)成長整型加入到累計值中,如此類推直至處理完截取出來的所有字符,此時的累計值就能夠代表用戶的分片索引值,完成了“字符串->整型”的轉(zhuǎn)換
- 對上一步的累計值進行求模,得到邏輯分片號
- 再根據(jù)邏輯分片號,查映射表,直接得到物理分片號
-
開發(fā)注意點
- 【分片索引】1,必須是字符串
- 【分片索引】2,最大物理分片配置方法是,讓partitionCount[]數(shù)組和等于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[]數(shù)組和等于1,例如“<property name="partitionLength">2880</property><property name="partitionCount">1</property>”
- 【分片索引】4,partitionLength和partitionCount被當(dāng)做兩個逗號分隔的一維數(shù)組,它們之間的點乘必須在[1, 2880]范圍內(nèi)
- 【分片索引】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>”是不同的分片結(jié)果
- 【分片索引】6,分片索引字段長度小于用戶指定的截取長度時,截取長度會安全減少到符合分片索引字段長度
- 【數(shù)據(jù)分布】1,分片索引字段截取越長則越有利于數(shù)據(jù)均勻分布
- 【數(shù)據(jù)分布】2,分片索引字段的內(nèi)容重復(fù)率越低則越有利于數(shù)據(jù)均勻分布
-
運維注意點
- 【擴容】1,預(yù)先過量分片,并且不改變partitionCount和partitionLength點乘結(jié)果,也不改變截取設(shè)置hashSlice時,可以避免數(shù)據(jù)再平衡,只需進行涉及數(shù)據(jù)的遷移
- 【擴容】2,若需要改變partitionCount和partitionLength點乘結(jié)果,或,改變截取設(shè)置hashSlice時,需要數(shù)據(jù)再平衡
- 【縮容】1,預(yù)先過量分片,并且不改變partitionCount和partitionLength點乘結(jié)果,也不改變截取設(shè)置hashSlice時,可以避免數(shù)據(jù)再平衡,只需進行涉及數(shù)據(jù)的遷移
- 【縮容】2,若需要改變partitionCount和partitionLength點乘結(jié)果,或,改變截取設(shè)置hashSlice時,需要數(shù)據(jù)再平衡
-
配置注意點
- 【配置項】1,在rule.xml中,可配置項為<property name="partitionLength">、<property name="partitionCount">和<property name="hashSlice">
- 【配置項】2,在rule.xml中配置<property name="partitionLength">標(biāo)簽,內(nèi)容形式為“<物理分片持有的虛擬分片數(shù)>[,<物理分片持有的虛擬分片數(shù)>,...<物理分片持有的虛擬分片數(shù)>]”,<物理分片持有的虛擬分片數(shù)>必須是整型,<物理分片持有的虛擬分片數(shù)>從左到右與同順序的<物理分片數(shù)>對應(yīng),partitionLength和partitionCount的點乘結(jié)果必須在[1, 2880]范圍內(nèi)
- 【配置項】3,在rule.xml中配置<property name="partitionCount">標(biāo)簽,內(nèi)容形式為“<物理分片數(shù)>[,<物理分片數(shù)>,...<物理分片數(shù)>]”,其中<物理分片數(shù)>必須是整型,<物理分片數(shù)>按從左到右的順序與同順序的<物理分片持有的虛擬分片數(shù)>對應(yīng),物理分片的編號從左到右連續(xù)遞進,partitionLength和partitionCount的點乘結(jié)果必須在[1, 2880]范圍內(nèi)
- 【配置項】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>”的分片結(jié)果是“第一個物理分片持有頭512個邏輯分片,第二個物理分片持有緊接著的256個邏輯分片,第三個物理分片持有最后256個邏輯分片”,相對的,“<property name="partitionLength">256,512</property><property name="partitionCount">2,1</property>”的分片結(jié)果則是“第一個物理分片持有頭256個邏輯分片,第二個物理分片持有緊接著的256個邏輯分片,第三個物理分片持有最后512個邏輯分片”
- 【配置項】6,partitionLength[]的元素全部為1時,這時候partitionCount數(shù)組和等于partitionLength和partitionCount的點乘,物理分片和邏輯分片就會一一對應(yīng),該分片算法等效于直接取余
- 【配置項】7,在rule.xml中配置<property name="hashSlice">標(biāo)簽,從分片索引字段的第幾個字符開始截取到第幾個字符:若希望從首字符開始截取k個字符(k為正整數(shù)),配置的內(nèi)容形式可以為“0:k”、“k”或“:k”;若希望從末字符開始截取k個字符(k為正整數(shù)),則配置的內(nèi)容形式可以為“-k:0”、“-k”或“-k:”;若希望從頭第m個字符起算截取n個字符(m和n都是正整數(shù)),則先計算出i=m-1和j=i+n-1,配置的內(nèi)容形式為“i:j”;若希望從尾第m個字符起算截取從尾算起的n個字符(m和n都是正整數(shù)),則先計算出i=-m+n-1,配置的內(nèi)容形式可以為“-m:i”;若希望不截取,則配置的內(nèi)容形式可以為“0:0”、“0:”、“:0”或 “:”