分庫分表實踐-Sharding-JDBC


最近在做一些涉及分庫分表的需求,正好周末有點時間就簡單做下總結,也方便自己以后查看。
本文只講述使用Sharding-JDBC做分庫分表的一些實踐經驗,如果有錯誤歡迎大家指出。

什么是Sharding-JDBC


Sharding-jdbc是當當網開源的一款客戶端代理中間件。Sharding-jdbc包含分庫分片和讀寫分離功能。對應用的代碼沒有侵入型,幾乎沒有任何改動,兼容主流orm框架,主流數據庫連接池。目前屬於Apache的孵化項目ShardingSphere。
Sharding-jdbc定位為輕量級Java框架,在Java的JDBC層提供的額外服務。 它使用客戶端直連數據庫,以jar包形式提供服務,無需額外部署和依賴,可理解為增強版的JDBC驅動,完全兼容JDBC和各種ORM框架。
適用於任何基於JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
支持任何第三方的數據庫連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
支持任意實現JDBC規范的數據庫。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92標准的數據庫。

官方文檔地址

ShardingSphere:https://shardingsphere.apache.org/
GitHub的地址:https://github.com/apache/incubator-shardingsphere

一些建議和說明

不過我這里建議大家可以簡單過下官方文檔,因為文檔並不全面或者說感覺並不是最新的。
建議大家重點可以放在git上官方的examples
目前官方最新的版本是4.0,如果使用springboot創建,可以使用下面的依賴即可。

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0</version>
</dependency>

Sharding-jdbc功能強大,但是本文重點在於下面幾點,未涉及的地方可以翻閱文檔查看。
1、單庫分表
2、分庫分表(含分庫單表)
3、分表后的查詢
4、分表事務處理
無論上述哪種分庫亦或是分表類型,核心無非是下面幾個配置:
1、配置數據源,明確你有多少個數據源
2、定義表名,分表的邏輯表名(t_order)和所有物理表名(t_order_0,t_order_1)
3、定義分庫列以及分庫算法
4、定義分表列以及分表算法

代碼實現

單庫分表

sharding-jdbc優勢就是對代碼沒有侵入性,基本上不用動我們原來的代碼,只是將相關數據庫連接的配置更換為sharding的配置即可。
以我的個人實踐項目為例:
原來不分表時的配置:

#項目配置
spring:
  #數據連接配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xxx.xx.xx.xx:3306/yyms?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: xxx
    password: xxx

使用sharding后的配置

# 分表配置
spring:
  shardingsphere:
    datasource:
      names: yyms
      yyms:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://xxx.xx.xx.xx:3306/yyms?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
        username: xx
        password: xxx
    sharding:
      tables:
        # 表名
        sys_log:
          actual-data-nodes: yyms.sys_log_$->{0..1}
          # 分表配置,根據id分表
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: sys_log_$->{id % 2}
          # 配置字段的生成策略,column為字段名,type為生成策略,sharding默認提供SNOWFLAKE和UUID兩種,可以自己實現其他策略
          key-generator:
            column: id
            type: SNOWFLAKE
    props:
      sql:
        show: true

上面的配置基本上就實現了單庫對sys_log表的拆分,根據id取模算法,拆分為sys_log_0和sys_log_1兩張表。代碼層面沒有任何改動就實現了拆分,拆分后效果圖如下。

注意哦,sys_log表拆分后是實際不存在的。
當然了,使用官方的默認配置很多時候並不能滿足我們的需求。
假如拿到一條數據的id后再去計算數據在哪個庫,無疑對我們日常的運維維護工作造成極大的不便。這里我們可以通過一些簡單的自定義開發配置實現。
比如我想要id最后一位展示數據所處表所在序號。

多庫分表

先展示個多庫單表的案例

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1
      ds_1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://xxxxxx:3306/ds1?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
        username: xxxx
        password: xxx
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://xxxxx:3306/ds0?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
        username: xxxx
        password: xxxx
    sharding:
      default-data-source-name: ds0
      default-database-strategy:
        inline:
          sharding-column: id
          algorithm-expression: ds$->{id % 2}
      tables:
        sys_log:
          actual-data-nodes: ds$->{0..1}.sys_log
          key-generator:
            column: id
            type: SNOWFLAKE
            props:
              worker:
                id: 123

把單張表拆分到多個庫,同樣使用sys_log。效果圖如下:

其實分庫分表無非就是上面兩種模式的集合,具體配置的選項,可以參考官方案例配置》》》我是鏈接

分庫分表后的查詢

select * from sys_log where id='444271380247588864'
接着上面的案例,以上面的語句為例,id為分庫列,sharding經過解析后定位到對應的數據源,直接執行下面的查詢。
select * from sys_log where id='444271380247588864'
假如我們的查詢調節不包含分庫列,以下面的語句為例:
select * from sys_log where user_name='zhangsan
執行后出現兩條sql語句。我們在兩個庫均為5條數據,查詢后的結果集為10條數據,符合我們的預期。
數據庫:

結果集:

結論:當搜索條件含有分庫列(分表列),這時候sharing會首先調用分庫分表策略類,直接找到對應的數據庫和對應子表。而當搜索條件不含有分庫列時,這時候引擎就不會再調用策略類了,而是會直接認定目標庫為全部庫或表,上述案例中目標庫就是,[ds0,ds1]兩個數據源,既然目標庫有兩個,后面生成的DataNode,TableUnits,PreparedStatementUnit 將是以前數量的兩倍,所以這回,引擎最終將會發起多個sql語句的並發執行,並合並最終的結果再返回。

分庫分表不支持語法注意

https://shardingsphere.apache.org/document/current/cn/features/sharding/use-norms/sql/#不支持項

分庫分表后的事務

Sharding-Sphere同時支持XA和柔性事務,它允許每次對數據庫的訪問,可以自由選擇事務類型。分布式事務對業務操作完全透明,極大地降低了引入分布式事務的成本。
分布式事務我感覺在官方的文檔和案例中寫的已經是比較完善的了,這里大家可以參考:我是鏈接 官方案例實現,這里就不在贅述了。
最后是項目的參考代碼:https://github.com/allanzhuo/yyms


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM