分庫分表-sharding-jdbc生產實踐

學習思路

  1. 快速啓動配置講解
  2. 五種分片策略
  3. 四種分片算法
  4. 文末有git地址

一、快速啓動配置講解

1、引入jar包

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

2、執行spring-cloud-example\sharding-sphere\script目錄下sql

3、配置數據源、分片字段、規則等

本文基於mysql

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
        jdbc-url: jdbc:mysql://localhost:3306/user?userUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        username: root
        password: root
      ds1:
        jdbc-url: jdbc:mysql://localhost:3306/user2019?userUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        username: root
        password: root
        minIdle: 10
        ##其它屬性自己加

    sharding:
      ## 設置默認數據源
      default-data-source-name: ds0
      ## 默認分庫規則
      default-database-strategy:
        standard:
          precise-algorithm-class-name: com.murphy.shardingjdbc.sharding.PreciseAlgorithm
          shardingColumn: user_id
      tables:
        user:
          ##設置每張表策略,可以覆蓋默認策略五規則@see org.apache.shardingsphere.core.yaml.config.sharding.YamlShardingStrategyConfiguration
          databaseStrategy:
            complex:
              shardingColumns: id
              ##複合分片
              algorithmClassName: com.murphy.shardingjdbc.sharding.ComplexAlgorithm
          ## 這段是sharding的表達式,用來確認分片的範圍從數據源0-1
          actual-data-nodes: ds$->{0..1}.user
        user_message:
          actual-data-nodes: ds$->{0..1}.user_message


logging:
  level:
    com.murphy.shardingjdbc.mapper: debug

mybatis:
  configuration:
    map-underscore-to-camel-case: true

解釋:

  1. names:你分了多少個庫就寫多少個別名用逗號分隔,注意要和下面的數據源配置保持一致
  2. ds0,ds1,dsn跟平時配置數據源一樣
  3. 設置默認的數據源,默認分片規則,分片字段(比如我們用user_id)
  4. 表配置,每個表可單獨設置分片規則(比如:我們上面默認按user_id分片,但在user表這個字段的字段名是id,這個時候我們可以爲user表單獨設置規則)(如配置中的user表)
  5. 如果表使用默認規則只需要配置庫對應的表即可(如配置中的user_message表)
  6. 如果表無分片規則,如配置表這樣的全局表:無需配置任何規則,只需要在默認數據庫有表即可,其它庫不需要(匹配不到規則走默認庫)(如:config_info表)

4、編寫分片規則算法

我們在配置裏看到兩個分片算法:接下來我們着重看系統內部提供的四種分片算法

com.murphy.shardingjdbc.sharding.PreciseAlgorithm

com.murphy.shardingjdbc.sharding.ComplexAlgorithm

二、五種分片策略講解

就是我們配置文件裏的default-database-strategy.standard和databaseStrategy.complex

我們這裏配置的是databaseStrategy:數據源分片策略

當然還有表分片策略,跟數據源配置大同小異,我們這裏以數據源爲主:tableStrategy

分片策略:分片鍵+分片算法(分片鍵:將數據庫水平拆分的關鍵字段;分片算法:把分片鍵的值按照一定的算法分配到不同的數據源)

主要類:org.apache.shardingsphere.core.yaml.config.sharding.YamlShardingStrategyConfiguration

public class YamlShardingStrategyConfiguration implements YamlConfiguration {
    
    private YamlStandardShardingStrategyConfiguration standard;
    
    private YamlComplexShardingStrategyConfiguration complex;
    
    private YamlHintShardingStrategyConfiguration hint;
    
    private YamlInlineShardingStrategyConfiguration inline;
    
    private YamlNoneShardingStrategyConfiguration none;
}

1、standard(標準分片策略):處理類:org.apache.shardingsphere.core.strategy.route.standard.StandardShardingStrategy

提供對SQL語句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。

StandardShardingStrategy只支持單分片鍵,提供PreciseShardingAlgorithm和RangeShardingAlgorithm兩個分片算法。

PreciseShardingAlgorithm是必選的,用於處理=和IN的分片。

RangeShardingAlgorithm是可選的,用於處理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND將按照全庫路由處理

2、complex(符合分片策略):處理類:org.apache.shardingsphere.core.strategy.route.complex.ComplexShardingStrategy

提供對SQL語句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。

ComplexShardingStrategy支持多分片鍵,可根據業務自定義算法實現,提供ComplexKeysShardingAlgorithm分片算法

3、hint(hint表達式分片策略):處理類:org.apache.shardingsphere.core.strategy.route.hint.HintShardingStrategy

通過hint表達式,而非SQL解析做分片,對應算法:HintShardingAlgorithm

4、inline(行表達式分片策略):處理類:org.apache.shardingsphere.core.strategy.route.inline.InlineShardingStrategy

使用Groovy的表達式,提供對SQL語句中的=和IN的分片操作支持,只支持單分片鍵。對於簡單的分片算法,可以通過簡單的配置使用,從而避免繁瑣的Java代碼開發,如: t_user_$->{u_id % 8} 表示t_user表根據u_id模8,而分成8張表,表名稱爲t_user_0t_user_7

5、none(不分片策略)處理類:org.apache.shardingsphere.core.strategy.route.none.NoneShardingStrategy

查詢所有的分片,謹慎使用(配置了分片表,單sql中沒有分片鍵)

三、四種分片算法

分片策略裏已經將策略提供的算法進行了對應,可看第三部分

主要在sharding-core-api包下的org.apache.shardingsphere.api.sharding.standard目錄下

1、PreciseShardingAlgorithm(精確切分算法):

             用於處理使用單一鍵作爲分片鍵的=與IN進行分片的場景(項目中的user_id分片,項目中最常用的)

2、RangeShardingAlgorithm(範圍切分算法):

            用於處理使用單一鍵作爲分片鍵的BETWEEN AND、>、<、>=、<=進行分片的場景(這個用於無規律的範圍,一般不用)

3、HintShardingAlgorithm(無分片鍵算法):

             用於處理使用Hint行分片的場景

4、ComplexKeysShardingAlgorithm(複雜鍵切分算法):

             用於處理使用多鍵作爲分片鍵進行分片的場景,包含多個分片鍵的邏輯較複雜,需要應用開發者自行處理其中的複雜度

 

面對複雜分片算法,一般都是初期沒設計好,後期分片的時候要用多個字段用業務邏輯補,要根據不同的坑不同設計

四、問題   

1、如果按用戶id來分庫,那麼按手機號查詢該怎麼處理

  1. 可在數據庫和分佈式緩存同時維護一套用戶id和手機號的映射關係,緩存可設置過期時間防止殭屍用戶
  2. 在數據庫主庫維護一套映射關係,關係表可按手機號取模進行分表

2、如果用戶id分片,id是自增的該怎麼處理

  1. 可以按用戶id區間遞增分片,不用洗數據,如db1[1-1000W];db2[1000W-2000W],但存在訪問熱度問題
  2. 如果用戶id用日期生成(雪花算法)可按日期分片,但存在數據分佈不均、訪問熱度問題

 

涉及代碼git地址:https://gitee.com/carpentor/spring-cloud-example

公衆號主要記錄各種源碼、面試題、微服務技術棧,幫忙關注一波,非常感謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章