溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用分庫分表Sharding-JDBC

發布時間:2021-10-21 17:18:21 來源:億速云 閱讀:317 作者:iii 欄目:編程語言
# 如何使用分庫分表Sharding-JDBC

## 目錄
- [一、分庫分表核心概念](#一分庫分表核心概念)
  - [1.1 什么是分庫分表](#11-什么是分庫分表)
  - [1.2 垂直拆分與水平拆分](#12-垂直拆分與水平拆分)
  - [1.3 分庫分表適用場景](#13-分庫分表適用場景)
- [二、Sharding-JDBC架構解析](#二sharding-jdbc架構解析)
  - [2.1 核心組件與工作原理](#21-核心組件與工作原理)
  - [2.2 與MyCat對比](#22-與mycat對比)
  - [2.3 版本演進與新特性](#23-版本演進與新特性)
- [三、基礎環境搭建](#三基礎環境搭建)
  - [3.1 依賴配置](#31-依賴配置)
  - [3.2 數據源配置](#32-數據源配置)
  - [3.3 分片規則配置](#33-分片規則配置)
- [四、分片策略詳解](#四分片策略詳解)
  - [4.1 標準分片策略](#41-標準分片策略)
  - [4.2 復合分片策略](#42-復合分片策略)
  - [4.3 Hint分片策略](#43-hint分片策略)
  - [4.4 不分片策略](#44-不分片策略)
- [五、分布式事務實現](#五分布式事務實現)
  - [5.1 XA事務](#51-xa事務)
  - [5.2 Seata柔性事務](#52-seata柔性事務)
  - [5.3 BASE事務](#53-base事務)
- [六、實戰案例](#六實戰案例)
  - [6.1 電商訂單分庫分表](#61-電商訂單分庫分表)
  - [6.2 多租戶SAAS系統](#62-多租戶saas系統)
  - [6.3 物聯網時序數據](#63-物聯網時序數據)
- [七、性能優化](#七性能優化)
  - [7.1 路由優化](#71-路由優化)
  - [7.2 合并執行優化](#72-合并執行優化)
  - [7.3 連接池配置](#73-連接池配置)
- [八、運維監控](#八運維監控)
  - [8.1 指標監控集成](#81-指標監控集成)
  - [8.2 鏈路追蹤](#82-鏈路追蹤)
  - [8.3 慢查詢分析](#83-慢查詢分析)
- [九、常見問題解決方案](#九常見問題解決方案)
  - [9.1 分布式ID生成](#91-分布式id生成)
  - [9.2 跨庫JOIN處理](#92-跨庫join處理)
  - [9.3 分布式序列問題](#93-分布式序列問題)
- [十、未來發展趨勢](#十未來發展趨勢)
  - [10.1 云原生支持](#101-云原生支持)
  - [10.2 多模異構支持](#102-多模異構支持)
  - [10.3 智能化方向](#103-智能化方向)

## 一、分庫分表核心概念

### 1.1 什么是分庫分表

分庫分表是數據庫水平擴展的核心技術手段,主要解決單機數據庫在數據量增長時出現的性能瓶頸問題。當單表數據量超過500萬行或數據庫實例QPS超過3000時,就應該考慮分庫分表方案。

**技術本質**:通過數據分片(Sharding)將數據集分散到不同的物理節點,使每個節點只處理部分數據,從而提升整體系統的處理能力。

### 1.2 垂直拆分與水平拆分

#### 垂直拆分(Vertical Partitioning)
```sql
-- 原始用戶表
CREATE TABLE user (
  id BIGINT,
  username VARCHAR(50),
  password VARCHAR(100),
  profile_json TEXT,
  login_log TEXT
);

-- 拆分后
CREATE TABLE user_basic (
  id BIGINT,
  username VARCHAR(50),
  password VARCHAR(100)
);

CREATE TABLE user_profile (
  user_id BIGINT,
  profile_json TEXT
);

水平拆分(Horizontal Partitioning)

// 按用戶ID范圍分片
shardingRuleConfig.getTableRuleConfigs().add(
    TableRuleConfiguration.builder("t_order")
        .actualDataNodes("ds${0..1}.t_order_${0..15}")
        .databaseShardingStrategy(
            new StandardShardingStrategyConfiguration("user_id", "dbShardingAlgorithm"))
        .tableShardingStrategy(
            new StandardShardingStrategyConfiguration("order_id", "tableShardingAlgorithm"))
        .build());

1.3 分庫分表適用場景

場景類型 典型特征 解決方案
高并發讀寫 QPS > 5000 分庫分散壓力
大數據量存儲 單表 > 500萬行 分表存儲
地理分布式訪問 跨地域訪問延遲高 按地域分庫
多租戶系統 租戶數據隔離需求 按租戶ID分庫

二、Sharding-JDBC架構解析

2.1 核心組件與工作原理

graph TD
    A[應用代碼] --> B[Sharding-JDBC Driver]
    B --> C[SQL解析引擎]
    C --> D[路由引擎]
    D --> E[改寫引擎]
    E --> F[執行引擎]
    F --> G[結果歸并]
    G --> H[返回結果]

關鍵組件說明: 1. SQL解析:基于Apache Calcite實現SQL語法樹解析 2. 路由引擎:支持精確路由、范圍路由、廣播路由等多種模式 3. 執行引擎:自動建立多線程執行管道 4. 歸并引擎:支持流式歸并、內存歸并等多種方式

2.2 與MyCat對比

特性 Sharding-JDBC MyCat
架構模式 客戶端直連 代理層
性能損耗 % 15%-20%
功能完整性 分片+分布式事務 分片+集群管理
運維復雜度 低(無中間件) 高(需維護代理)
版本迭代 活躍(Apache維護) 社區維護

2.3 版本演進與新特性

5.x版本重大改進: 1. 可插拔架構:支持SPI擴展 2. 分布式事務:XA/SAGA/SEATA全支持 3. 數據加密:列級別透明加密 4. 影子庫壓測:全鏈路壓測支持

三、基礎環境搭建

3.1 依賴配置

Maven核心依賴:

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core</artifactId>
    <version>5.3.2</version>
</dependency>
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>4.0.3</version>
</dependency>

Spring Boot自動配置:

spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost:3306/ds0
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456

3.2 數據源配置

YAML格式配置示例:

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/ds0
        username: root
        password: 123456
        connection-timeout: 30000
        idle-timeout: 600000
        max-lifetime: 1800000
        maximum-pool-size: 20

3.3 分片規則配置

Java API配置方式:

// 分片算法配置
Properties dbShardingProps = new Properties();
dbShardingProps.setProperty("algorithm-expression", "ds${user_id % 2}");
ShardingSphereAlgorithmConfiguration dbShardingAlgorithm = 
    new ShardingSphereAlgorithmConfiguration("INLINE", dbShardingProps);

// 表規則配置
ShardingTableRuleConfiguration orderTableRule = new ShardingTableRuleConfiguration(
    "t_order", "ds${0..1}.t_order_${0..15}");
orderTableRule.setDatabaseShardingStrategy(
    new StandardShardingStrategyConfiguration("user_id", "dbShardingAlgorithm"));
orderTableRule.setTableShardingStrategy(
    new StandardShardingStrategyConfiguration("order_id", "tableShardingAlgorithm"));

四、分片策略詳解

4.1 標準分片策略

精確分片算法實現:

public class OrderDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    @Override
    public String doSharding(Collection<String> availableTargetNames, 
                           PreciseShardingValue<Long> shardingValue) {
        for (String each : availableTargetNames) {
            if (each.endsWith(shardingValue.getValue() % 2 + "")) {
                return each;
            }
        }
        throw new IllegalArgumentException();
    }
}

范圍分片算法示例:

public class OrderRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                       RangeShardingValue<Long> shardingValue) {
        Set<String> result = new LinkedHashSet<>();
        Long lower = shardingValue.getValueRange().lowerEndpoint();
        Long upper = shardingValue.getValueRange().upperEndpoint();
        for (long i = lower; i <= upper; i++) {
            for (String each : availableTargetNames) {
                if (each.endsWith(i % 2 + "")) {
                    result.add(each);
                }
            }
        }
        return result;
    }
}

4.2 復合分片策略

多字段分片配置:

spring:
  shardingsphere:
    sharding:
      tables:
        t_order:
          actual-data-nodes: ds$->{0..1}.t_order_$->{0..15}
          database-strategy:
            complex:
              sharding-columns: user_id,order_date
              algorithm-class-name: com.example.ComplexShardingAlgorithm

復合算法實現:

public class ComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                       ComplexKeysShardingValue<Comparable<?>> shardingValue) {
        Map<String, Collection<Comparable<?>>> columnValues = shardingValue.getColumnNameAndShardingValuesMap();
        Collection<Comparable<?>> userIds = columnValues.get("user_id");
        Collection<Comparable<?>> orderDates = columnValues.get("order_date");
        
        Set<String> result = new HashSet<>();
        // 實現自定義復合分片邏輯
        for (Comparable<?> userId : userIds) {
            for (Comparable<?> orderDate : orderDates) {
                int dbSuffix = (userId.hashCode() & Integer.MAX_VALUE) % 2;
                int tableSuffix = orderDate.hashCode() % 16;
                result.add(String.format("ds%d.t_order_%d", dbSuffix, tableSuffix));
            }
        }
        return result;
    }
}

4.3 Hint分片策略

強制路由配置:

// 設置分片值
HintManager.getInstance().setDatabaseShardingValue(1);

try {
    // 執行SQL(將強制路由到ds1)
    orderRepository.selectAll();
} finally {
    HintManager.clear();
}

Hint算法實現:

public class OrderHintShardingAlgorithm implements HintShardingAlgorithm<Integer> {
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                       HintShardingValue<Integer> shardingValue) {
        Collection<String> result = new ArrayList<>();
        for (String each : availableTargetNames) {
            for (Integer value : shardingValue.getValues()) {
                if (each.endsWith(value.toString())) {
                    result.add(each);
                }
            }
        }
        return result;
    }
}

4.4 不分片策略

廣播表配置:

spring:
  shardingsphere:
    sharding:
      broadcast-tables: t_config

綁定表配置:

spring:
  shardingsphere:
    sharding:
      binding-tables:
        - t_order,t_order_item

五、分布式事務實現

5.1 XA事務

配置XA事務管理器:

spring:
  shardingsphere:
    props:
      xa-transaction-manager-type: Atomikos

事務使用示例:

@ShardingSphereTransactionType(TransactionType.XA)
@Transactional
public void placeOrder(Order order) {
    // 業務邏輯
}

5.2 Seata柔性事務

Seata集成配置:

spring:
  shardingsphere:
    props:
      seata:
        tx-service-group: my_test_tx_group

AT模式示例:

@ShardingSphereTransactionType(TransactionType.BASE)
@Transactional
public void updateOrder(Order order) {
    // 第一階段:執行業務SQL并生成undo log
    orderMapper.update(order);
    // 第二階段:由Seata自動提交/回滾
}

5.3 BASE事務

Saga模式配置:

@ShardingSphereTransactionType(TransactionType.SAGA)
@SagaStart(timeoutSeconds = 300)
public void createOrder(Order order) {
    // 正向操作
    orderService.create(order);
    inventoryService.reduce(order.getItemId(), order.getCount());
    
    // 補償操作定義
    @Compensate
    public void compensateCreate(Order order) {
        orderService.delete(order.getId());
        inventoryService.increase(order.getItemId(), order.getCount());
    }
}

六、實戰案例

6.1 電商訂單分庫分表

場景特點: - 訂單量日均10萬+ - 需要按用戶維度查詢 - 歷史訂單需要歸檔

分片方案

spring:
  shardingsphere:
    sharding:
      tables:
        t_order:
          actual-data-nodes: ds$->{0..3}.t_order_$->{0..15}
          database-strategy:
            inline:
              sharding-column: user_id
              algorithm-expression: ds$->{user_id % 4}
          table-strategy:
            standard:
              sharding-column: order_time
              precise-algorithm-class-name: com.example.OrderTimePreciseShardingAlgorithm
              range-algorithm-class-name: com.example.OrderTimeRangeShardingAlgorithm

6.2 多租戶SAAS系統

場景特點: - 租戶數量超過1000+ - 需要嚴格數據隔離 - 支持自定義租戶分片策略

解決方案

public class TenantShardingAlgorithm implements PreciseShardingAlgorithm<String> {
    @Override
    public String doSharding(Collection<String> availableTargetNames,
                           PreciseShardingValue<String> shardingValue) {
        // 根據租戶ID哈希分片
        int hash = Math.abs(shardingValue.getValue().hashCode());
        int index = hash % availableTargetNames.size();
        return new ArrayList<>(availableTargetNames).get(index);
    }
}

6.3 物聯網時序數據

特殊需求: - 時間序列數據 - 需要定期自動創建新表 - 支持冷熱數據分離

動態分片方案

public class TimeSeriesShardingAlgorithm implements PreciseShardingAlgorithm<Date> {
    private static final DateTimeFormatter TABLE_FORMAT = 
        DateTimeFormatter.ofPattern("yyyy_MM");

    @Override
    public String doSharding(Collection<String> availableTargetNames,
                           PreciseShardingValue<Date> shardingValue) {
        LocalDate date = shardingValue.getValue().toInstant()
            .atZone(ZoneId.systemDefault()).toLocalDate();
        String tableSuffix = date.format(TABLE_FORMAT);
        return availableTargetNames.stream()
            .filter(each -> each.endsWith(tableSuffix))
            .findFirst()
            .orElseThrow(() -> new IllegalArgumentException("No table for date " + date));
    }
}

七、性能優化

7.1 路由優化

最佳實踐: 1. 避免全庫全表掃描:

-- 錯誤寫法(導致廣播路由)
SELECT * FROM t_order WHERE status = 1;

-- 正確寫法(帶上分片鍵)
SELECT * FROM t_order WHERE user_id = 123 AND status = 1;
  1. 索引優化建議:
-- 分片鍵必須包含在索引中
ALTER TABLE t_order ADD INDEX idx_user_status (user_id, status);

7.2 合并執行優化

配置參數調優:

spring:
  shardingsphere:
    props:
      max.connections.size.per.query: 5  # 每個查詢最大連接數
      executor.size: 20                  # 執行線程池大小
      kernel.executor.size: 20           # 內核線程池大小

7.3 連接池配置

HikariCP優化建議: “`yaml spring: shardingsphere: datasource: ds0: hikari: maximum-pool-size:

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女