1 添加依賴
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>${sharding.version}</version>
</dependency>
2 分庫分表數選擇
根據未來兩年的業務量,估算兩年的業務總量M,單表資料量不能超過N(需要看具體業務場景,欄位少的可以適量多一些,可與架構師及部門經驗豐富的同事探討,最大不要超過1000W);
總的分表數量K≥M/N,且K值向上取接近的最小2的次冪,
例如業務總量M=10億,單表數量N≤700W,則M/N≈143,向上取最小的2次冪為:143<2的8次方=256,故總的分表數量為256,
可將分表數設定的盡可能的小,一臺服務器存放多個庫,業務增長后,磁盤不足時,可將該服務器上的整個庫的資料遷移到新的服務器,
如總的分表數量為1024,可分為32個庫:db0~db31,每個庫分32張表:tb0~tb31,共16臺服務器:server0~server15,
具體劃分如下:
- server0上有db0庫和db16庫
- server1上有db1庫和db17庫
- ……
- server15上有db15庫和db31庫
如果業務發展一段時間后出現磁盤不足,可在申請16臺服務器:server16~server31
- server0上的db16庫遷移至server16
- server1上的db17庫遷移至server17
- ……
- server15上的db31庫遷移至server31
遷移后磁盤釋放50%空間
3 分片鍵(拆分鍵)選擇
分片鍵的選擇一定要具有明顯的業務特征,具體表現為:
- 常用的已知的具體值,查詢條件中要包含分片鍵,需要根據分片鍵確定在哪個庫表,如果查詢條件里沒有分片鍵,將會遍歷所有庫表,這種情況是不允許的;
- 分片鍵分辨度較高,比較分散,不能選擇分辨度不高的的欄位作為分片鍵,容易造成資料分布不均勻;
- 分片鍵不能有偏移,比如分片鍵某個值不能遠遠大于其他值,這種情況也會造成資料分布不均勻;
- 大小寫,如果分片鍵在某些表里不區分大小寫,那么分片鍵要統一大寫或小寫后用于分片,因此其他條件要考慮統一大小寫后的情況;
目前專案里使用的分片鍵為商家編碼,并統一為大寫,因為:
- 在查詢分庫分表資料時,商家編碼是已知的,所以查詢條件中包含商家編碼;
- 商家編碼較多,能夠保證按照商家編碼分片后資料基本是均勻分布的;
- 系統中不存在某個或某幾個商家編碼的資料量占據大部分的資料量;
4 分片演算法
inline: Groovy的Inline運算式,可以支持SQL陳述句中的=和IN的操作,InlineShardingStrategy只支持單分片鍵;這種方式是最常用的,也是目前專案中在使用的,
其他分片策略參考:Sharding-JDBC分片策略
4.1 分庫演算法
以32個庫為例:Math.abs(庫分片鍵.toUpperCase().hashCode()) % 32,將分片鍵商家編碼統一大寫后,取hashCode的絕對值,對32取模,32為分庫數;
通用公式為:Math.abs(庫分片鍵.toUpperCase().hashCode()) % 分庫數
4.2 分表演算法
以每個庫32張表為例:(Math.abs(表分片鍵.toUpperCase().hashCode()) % 1024).intdiv(32),要保證分到某個庫的資料,均勻分布到該庫的每個表;
注意:此處不能直接用分庫的公式,因為某個商家計算后分配到第i庫,如果分表用同樣的公式,則也只能落到第i表,導致一個庫中只有一個表有資料,因此,需要先對一個較大的數取模,該較大的數為分庫數*分表數,記為m,本例中=32*32=1024,將hash后的值分散到0-1023之間,在除以32,則最終結果被分配到0-31之間,
通用公式為:(Math.abs(表分片鍵.toUpperCase().hashCode()) % 分庫數*分表數).intdiv(分庫數)
5 全域(分布式)主鍵
分庫分表,要求主鍵全域唯一,因為存在資料匯總的場景,如存放到ES、大資料等;因此不能使用資料庫自增方式,需要一種全域唯一的主鍵生成方式;
5.1 shardingjdbc提供的主鍵
1. 添加maven依賴
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>sharding-jdbc-self-id-generator</artifactId>
<version>1.4.2</version>
</dependency>
2. 在@Configuration類中創建Bean物件
@Bean
public IdGenerator getIdGenerator() {
return new CommonSelfIdGenerator();
}
3. 使用
@Autowired
private IdGenerator idGenerator;
@Test
public void generateId(){
long id = idGenerator.generateId().longValue();
......
}
5.2 雪花演算法生成主鍵
很多插件如sharding-jdbc, mybatis-plus提供了雪花演算法生成器,目前常用的是這種方式,生產的id時間上基本是有序的,使用很方便,
6 查詢條件沒有分片鍵如何處理
不允許沒有分片鍵的查庫操作;
查詢或更新庫操作條件里必須有分片鍵,否則就需要將分庫分表資料存放到ES或建立查詢條件與分片鍵的中間表;
ES或分片鍵中間表是為個別場景如頁面多條件查詢,用戶獲取不到分片鍵時采取的折中方案,絕大多數場景是能獲取到分片鍵的,如果獲取不到則可認為分片鍵的選取是不合理的,需要根據實際場景調整分片鍵,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/547443.html
標籤:Java
上一篇:單例模式
下一篇:jvm相關知識
