參考資料:猿天地 https://mp.weixin.qq.com/s/901rNhc4WhLCQ023zujRVQ 作者:尹吉歡
當單表的數量急劇上升,超過了1千萬以上,這個時候就要對表進行水平拆分。
表的水平拆分是什么?
就是將一個表拆分成N個表,就像一塊大石頭,搬不動,然后切割成10塊,這樣就能搬的動了。原理是一樣的。 除了能夠分擔數量的壓力,同時也能分散讀寫請求的壓力,當然這個得看你的分片算法了,合理的算法才能夠讓數據分配均勻並提升性能。 今天我們主要講單庫中進行表的拆分,也就是不分庫,只分表。
user表由原來的一個被拆分成了4個,數據會均勻的分布在這3個表中,也就是原來的user = user0 + user1 + user2 + user3。
技術選型:SpringBoot + Sharding-JDBC + MyBatis
1. 核心Jar包
同 垂直拆分
2. yml文件配置
# 數據源名稱集合,對應下面數據源配置的名稱 spring: main: allow-bean-definition-overriding: true shardingsphere: datasource: names: db1 # 主數據源 db1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db_user?characterEncoding=utf-8 username: **** password: **** sharding: tables: user: # 分表配置 actual-data-nodes.db1: user_${0..3} # inline 表達式 table-strategy.inline.sharding-column: id table-strategy.inline.algorithm-expression: user_${id.longValue()%4} props: # 開啟SQL顯示,默認false sql: show: true
- actual-data-nodes 配置分表信息,這邊用的inline表達式,翻譯過來就是db1.user0,db1.user1,db1.user2,db1.user3
- inline.sharding-column 分表的字段,這邊用id分表
- inline.algorithm-expression 分表算法行表達式,需符合groovy語法,上面的配置就是用id進行取模分片
如果我們有更復雜的分片需求,可以自定義分片算法來實現:
sharding: tables: user: # 分表字段 table-strategy.standard.sharding-column: id # 自定義分表算法類 table-strategy.standard.precise-algorithm-class-name: com.*.*.MyPreciseShardingAlgorithm
算法類:
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> { @Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) { for (String tableName : availableTargetNames) { if (tableName.endsWith(shardingValue.getValue() % 4 + "")) { return tableName; } } throw new IllegalArgumentException(); } }
在doSharding方法中你可以根據參數shardingValue做一些處理,最終返回這條數據需要分片的表名稱即可。
除了單列字段分片,還支持多字段分片,大家可以自己去看文檔操作一下。
需要分表的進行配置,不需要分表的無需配置,數據庫操作代碼一行都不用改變。
如果我們要在單庫分表的基礎上,再做讀寫分離,同樣很簡單,只要多配置一個從數據源就可以了,配置如下:
spring.shardingsphere.datasource.names=master,slave # 主數據源 spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8 spring.shardingsphere.datasource.master.username=root spring.shardingsphere.datasource.master.password=123456 # 從數據源 spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.slave.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8 spring.shardingsphere.datasource.slave.username=root spring.shardingsphere.datasource.slave.password=123456 # 分表配置 spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user_${0..3} spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue()%4} # 讀寫分離配置 spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=slave