最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用ShardingJDBC進行數(shù)據(jù)分片以及讀寫分離

 更新時間:2024年01月31日 08:22:44   作者:一只愛擼貓的程序猿  
ShardingJDBC是一個輕量級的Java框架,提供了數(shù)據(jù)分片、讀寫分離、分布式主鍵生成等數(shù)據(jù)訪問功能,本文將給大家介紹如何使用ShardingJDBC進行數(shù)據(jù)分片以及讀寫分離,需要的朋友可以參考下

簡述

  • ShardingJDBC: 它是一個輕量級的Java框架,提供了數(shù)據(jù)分片、讀寫分離、分布式主鍵生成等數(shù)據(jù)訪問功能。ShardingJDBC 直接嵌入在應用程序中,不需要通過中間件代理的方式實現(xiàn)數(shù)據(jù)庫訪問。
  • 多數(shù)據(jù)源: 在 ShardingJDBC 中,多數(shù)據(jù)源指的是將數(shù)據(jù)儲存到多個數(shù)據(jù)庫中。數(shù)據(jù)根據(jù)某種分片策略(如按照ID范圍、哈希值等)分布在不同的數(shù)據(jù)庫中。
  • 讀寫分離: 讀寫分離是通過配置主庫(寫操作)和從庫(讀操作)來實現(xiàn)的。應用程序?qū)懭氩僮髦饕槍χ鲙?,讀取操作可以分散到多個從庫中,從而提高數(shù)據(jù)庫的讀取性能和系統(tǒng)的可擴展性。

原理

ShardingJDBC 的核心組件和功能,包括一些相關代碼片段以更好地理解其工作原理。

1. SQL 解析

SQL 解析是 ShardingJDBC 處理流程的起點。ShardingJDBC 使用 ANTLR(另一個語言識別工具)作為 SQL 解析工具。

  • SQL解析類SQLParseEngine 是解析的入口點。它接收原始 SQL 語句并基于數(shù)據(jù)庫方言(MySQL、PostgreSQL 等)進行解析。
  • 解析過程:解析過程包括詞法分析和語法分析,用于構(gòu)建抽象語法樹(AST)。AST 提供了 SQL 結(jié)構(gòu)的詳細視圖,包括表名、列名、條件等。

SQLParseEngine 源碼分析

public final class SQLParseEngine {
    private final DatabaseType databaseType;
    private final String sql;
    private final LexerEngine lexerEngine;
    private final SQLStatementParser statementParser;

    public SQLParseEngine(DatabaseType databaseType, String sql, Properties properties, List<SQLToken> sqlTokens) {
        this.databaseType = databaseType;
        this.sql = sql;
        Lexer lexer = LexerFactory.newInstance(databaseType, sql);
        this.lexerEngine = new LexerEngine(lexer);
        this.statementParser = SQLStatementParserFactory.newInstance(databaseType, lexerEngine);
    }

    public SQLStatement parse() {
        lexerEngine.nextToken();
        return statementParser.parse();
    }
}

在上面的代碼中,SQLParseEngine 使用了數(shù)據(jù)庫類型(DatabaseType)和 SQL 語句來初始化。它首先創(chuàng)建一個 Lexer(詞法解析器),然后使用這個 Lexer 創(chuàng)建一個 LexerEngine,并且基于數(shù)據(jù)庫類型創(chuàng)建相應的 SQL 語句解析器。parse 方法最終返回一個 SQL 語句對象(SQLStatement),這個對象代表了解析后的 SQL 語句。

2. 路由計算

路由是根據(jù)分片策略和解析出的 SQL 信息,確定 SQL 應該執(zhí)行在哪些具體的數(shù)據(jù)庫和表上。

  • 路由類ShardingRouter 負責執(zhí)行路由邏輯。
  • 路由策略:通過實現(xiàn) ShardingStrategy 接口的類(如 StandardShardingStrategyComplexShardingStrategy),根據(jù)分片鍵和分片算法確定目標數(shù)據(jù)源。

ShardingRouter 源碼分析

public final class ShardingRouter {
    private final ShardingRule shardingRule;

    public ShardingRouter(ShardingRule shardingRule) {
        this.shardingRule = shardingRule;
    }

    public RoutingResult route(final SQLStatement sqlStatement) {
        // 省略具體路由邏輯
    }
}

在這里,ShardingRouter 通過 ShardingRule(包含分片策略和規(guī)則)來進行初始化。route 方法接受一個 SQL 語句對象,并根據(jù)分片規(guī)則返回路由結(jié)果。

3. SQL 改寫

根據(jù)路由結(jié)果,ShardingJDBC 會改寫原始 SQL,使其適用于目標的物理數(shù)據(jù)庫和表。

  • 改寫類SQLRewriteEngine 負責 SQL 改寫。
  • 改寫過程:根據(jù)路由結(jié)果和 AST,SQLRewriteEngine 會修改表名、增加額外的條件等,生成最終要執(zhí)行的 SQL。

SQLRewriteEngine 源碼分析

public final class SQLRewriteEngine {
    private final SQLStatement sqlStatement;
    private final List<SQLToken> sqlTokens;

    public SQLRewriteEngine(SQLStatement sqlStatement) {
        this.sqlStatement = sqlStatement;
        this.sqlTokens = new LinkedList<>();
    }

    public String rewrite() {
        // 省略具體改寫邏輯
    }
}

這里的 SQLRewriteEngine 接收一個 SQL 語句對象,并根據(jù)路由結(jié)果和 SQL 語句中的令牌(SQLToken)列表來改寫 SQL。

4. 執(zhí)行計劃生成與執(zhí)行

生成 SQL 的執(zhí)行計劃并在相應的數(shù)據(jù)庫實例上執(zhí)行。

  • 執(zhí)行類ShardingExecuteEngine 負責管理 SQL 的執(zhí)行。
  • 執(zhí)行過程:它可能涉及到并行查詢、合并結(jié)果集等操作。對于寫操作,通常直接路由到主庫;對于讀操作,則可能涉及到多個從庫。
public class ShardingExecuteEngine implements AutoCloseable {
    private final ExecutorService executorService;

    public ShardingExecuteEngine(int executorSize) {
        this.executorService = Executors.newFixedThreadPool(executorSize);
    }

    // 省略執(zhí)行方法
}

ShardingExecuteEngine 使用一個線程池來執(zhí)行 SQL。這個類負責管理 SQL 的執(zhí)行過程,包括可能的并行查詢和結(jié)果集合并。

5. 結(jié)果集合并

對于查詢操作,ShardingJDBC 需要合并來自不同物理表或數(shù)據(jù)庫的結(jié)果集。

  • 合并類MergeEngine 負責結(jié)果集的合并。
  • 合并過程:根據(jù)不同的查詢類型(聚合查詢、排序查詢等),MergeEngine 使用不同的合并策略來確保返回給用戶的是一個統(tǒng)一的結(jié)果集。
public final class MergeEngine {
    public MergedResult merge(List<QueryResult> queryResults, SQLStatement sqlStatement) {
        // 省略合并邏輯
    }
}

MergeEngine 負責將來自不同物理表或數(shù)據(jù)庫的查詢結(jié)果合并成一個統(tǒng)一的結(jié)果集。它根據(jù) SQL 語句的類型(如聚合查詢、排序查詢)來應用不同的合并策略。

6. 分布式事務處理

處理分布式環(huán)境下的事務一致性。

  • 事務管理器ShardingTransactionManager 接口定義了事務管理的行為。
  • 具體實現(xiàn):如 XAShardingTransactionManager 用于處理 XA 類型的分布式事務。

ShardingTransactionManager 接口和 XAShardingTransactionManager 實現(xiàn)

public interface ShardingTransactionManager {
    void begin();
    void commit();
    void rollback();
    // 省略其他方法
}

public class XAShardingTransactionManager implements ShardingTransactionManager {
    // 實現(xiàn)分布式事務管理邏輯
}

ShardingTransactionManager 接口定義了事務管理的基本行為,如開始(begin)、提交(commit)和回滾(rollback)操作。XAShardingTransactionManager 是這個接口的一個實現(xiàn),用于處理 XA 類型的分布式事務。

我們將假設有兩個業(yè)務表:orderuser,并且這兩個表需要根據(jù)不同的策略進行分片。同時,我們將設置四個數(shù)據(jù)源(兩個主庫和兩個從庫)來實現(xiàn)讀寫分離。

實際案例

場景設定

  • 數(shù)據(jù)源ds0、ds0_slave、ds1ds1_slave。其中 ds0ds1 是主庫,ds0_slaveds1_slave 是從庫。
  • 業(yè)務表orderuser。
  • 分片策略
    • order 表按照訂單ID分片。
    • user 表按照用戶ID分片。
  • 讀寫分離:所有寫操作都發(fā)生在主庫,讀操作可以分配到從庫。

配置和代碼實現(xiàn)

添加依賴:

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

配置文件 application.yml:

spring:
  shardingsphere:
    datasource:
      names: ds0,ds0_slave,ds1,ds1_slave
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: YOUR_DRIVER_CLASS
        jdbc-url: JDBC_URL_FOR_DS0
        username: YOUR_USERNAME
        password: YOUR_PASSWORD
      ds0_slave:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: YOUR_DRIVER_CLASS
        jdbc-url: JDBC_URL_FOR_DS0_SLAVE
        username: YOUR_USERNAME
        password: YOUR_PASSWORD
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: YOUR_DRIVER_CLASS
        jdbc-url: JDBC_URL_FOR_DS1
        username: YOUR_USERNAME
        password: YOUR_PASSWORD
      ds1_slave:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: YOUR_DRIVER_CLASS
        jdbc-url: JDBC_URL_FOR_DS1_SLAVE
        username: YOUR_USERNAME
        password: YOUR_PASSWORD
    sharding:
      tables:
        order:
          actual-data-nodes: ds${0..1}.order_${0..1}
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: order_${id % 2}
          database-strategy:
            inline:
              sharding-column: user_id
              algorithm-expression: ds${user_id % 2}
          key-generator:
            type: SNOWFLAKE
            column: id
        user:
          actual-data-nodes: ds${0..1}.user_${0..1}
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: user_${id > 5000 ? 1 : 0}
          database-strategy:
            inline:
              sharding-column: id
              algorithm-expression: ds${id % 2}
          key-generator:
            type: SNOWFLAKE
            column: id
      master-slave-rules:
        ds0:
          master-data-source-name: ds0
          slave-data-source-names: ds0_slave
        ds1:
          master-data-source-name: ds1
          slave-data-source-names: ds1_slave

這段配置是用于設置 Apache ShardingSphere(ShardingJDBC 的一個部分)的 YAML 格式的配置文件,專門用于 Spring Boot 項目。它定義了數(shù)據(jù)源(包括主從數(shù)據(jù)源),表的分片策略,以及主從復制規(guī)則。讓我們逐個部分進行詳細解釋:

數(shù)據(jù)源配置

datasource:
  names: ds0,ds0_slave,ds1,ds1_slave
  ds0:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: YOUR_DRIVER_CLASS
    jdbc-url: JDBC_URL_FOR_DS0
    username: YOUR_USERNAME
    password: YOUR_PASSWORD
  ...
  • names: 定義了所有數(shù)據(jù)源的名稱,這里有四個數(shù)據(jù)源:ds0, ds0_slave, ds1, ds1_slave
  • ds0, ds0_slave, ds1, ds1_slave: 分別定義了四個數(shù)據(jù)源的詳細配置。
  • type: 數(shù)據(jù)源類型,這里使用的是 HikariCP 連接池。
  • driver-class-name: 數(shù)據(jù)庫驅(qū)動類。
  • jdbc-url: 數(shù)據(jù)庫的 JDBC URL。
  • usernamepassword: 數(shù)據(jù)庫的登錄用戶名和密碼。

分片配置

sharding:
  tables:
    order:
      actual-data-nodes: ds${0..1}.order_${0..1}
      table-strategy:
        inline:
          sharding-column: id
          algorithm-expression: order_${id % 2}
      database-strategy:
        inline:
          sharding-column: user_id
          algorithm-expression: ds${user_id % 2}
      key-generator:
        type: SNOWFLAKE
        column: id
    user:
      ...
  • sharding: 定義了分片的總體配置。
  • tables: 在這里定義具體的表和它們的分片策略。
  • order: 這是一個表的名稱。
  • actual-data-nodes: 定義實際的數(shù)據(jù)節(jié)點,ds${0..1}.order_${0..1} 表示 order 表在 ds0ds1 數(shù)據(jù)源上都有兩個分片,即 order_0order_1。
  • table-strategy: 定義表的分片策略。
    • sharding-column: 分片鍵,這里使用 id。
    • algorithm-expression: 分片算法表達式,這里是簡單的模 2 運算。
  • database-strategy: 定義數(shù)據(jù)庫的分片策略,類似于表的分片策略。
  • key-generator: 定義主鍵生成策略,這里使用的是雪花算法(SNOWFLAKE)。

主從配置

master-slave-rules:
  ds0:
    master-data-source-name: ds0
    slave-data-source-names: ds0_slave
  ds1:
    master-data-source-name: ds1
    slave-data-source-names: ds1_slave

實體類和數(shù)據(jù)訪問層:

定義 Order 和 User 實體類,以及對應的 JPA 倉庫或 MyBatis 映射。

Order 實體類

@Entity
@Table(name = "order")
public class Order {
    @Id
    private Long id;

    @Column(name = "user_id")
 private Long userId;

    @Column(name = "order_amount")
    private BigDecimal orderAmount;

 // 標準的構(gòu)造函數(shù)、getter 和 setter
    public Order() {
    }

    // ... 省略其他構(gòu)造函數(shù)、getter 和 setter 方法

    // ... 可以添加業(yè)務邏輯方法
}

User 實體類

@Entity
@Table(name = "user")
public class User {
    @Id
    private Long id;

    @Column(name = "username")
    private String username;

    @Column(name = "email")
    private String email;

    // 標準的構(gòu)造函數(shù)、getter 和 setter
    public User() {
    }

    // ... 省略其他構(gòu)造函數(shù)、getter 和 setter 方法

    // ... 可以添加業(yè)務邏輯方法
}

OrderRepository 接口

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    List<Order> findByUserId(Long userId);

    // ... 可以根據(jù)需要添加其他查詢方法
}

UserRepository 接口

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);

    // ... 可以根據(jù)需要添加其他查詢方法
}

補充一個mybatis的寫法:

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User findById(Long id);

    @Insert("INSERT INTO user (username, email) VALUES (#{username}, #{email})")
    void insert(User user);

    // 更多的 MyBatis SQL 映射可以根據(jù)需要添加
}

總結(jié)

ShardingJDBC 的源碼實現(xiàn)體現(xiàn)了其作為一個數(shù)據(jù)庫中間件框架的復雜性和靈活性。它將 SQL 解析、路由、改寫、執(zhí)行和結(jié)果集合并等多個步驟封裝成一系列高度解耦的組件和接口。這種設計使得 ShardingJDBC 能夠靈活地適應各種數(shù)據(jù)庫和 SQL 方言,同時提供豐富的分片策略和讀寫分離功能。

以上就是使用ShardingJDBC進行數(shù)據(jù)分片以及讀寫分離的詳細內(nèi)容,更多關于ShardingJDBC數(shù)據(jù)分片的資料請關注腳本之家其它相關文章!

相關文章

  • Springboot配置管理Externalized?Configuration深入探究

    Springboot配置管理Externalized?Configuration深入探究

    這篇文章主要介紹了Springboot配置管Externalized?Configuration深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • java求100以內(nèi)的素數(shù)示例分享

    java求100以內(nèi)的素數(shù)示例分享

    素數(shù)是指因數(shù)只有1和本身的數(shù)字,這篇文章主要介紹了java求100以內(nèi)的素數(shù)示例,需要的朋友可以參考下
    2014-03-03
  • 帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表

    帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表

    這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • SpringBoot調(diào)用第三方接口的幾種方式小結(jié)

    SpringBoot調(diào)用第三方接口的幾種方式小結(jié)

    在項目中調(diào)用第三方接口時,確實需要根據(jù)項目的技術棧、架構(gòu)規(guī)范以及具體的業(yè)務需求來選擇最適合的調(diào)用方式,下面我們就介紹幾種調(diào)用第三方接口的實現(xiàn)方式以及代碼示例,需要的朋友可以參考下
    2024-07-07
  • Java設計模式之橋模式(Bridge模式)介紹

    Java設計模式之橋模式(Bridge模式)介紹

    這篇文章主要介紹了Java設計模式之橋模式(Bridge模式)介紹,本文講解了為什么使用橋模式、如何實現(xiàn)橋模式、Bridge模式在EJB中的應用等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • Spring實現(xiàn)國際化與本地化的詳細步驟

    Spring實現(xiàn)國際化與本地化的詳細步驟

    在全球化背景下,應用支持多語言和本地化顯示是滿足不同地區(qū)用戶需求的關鍵,Spring 的國際化與本地化功能,能幫助開發(fā)者輕松實現(xiàn)應用的語言切換與區(qū)域適配,下面從核心概念、實現(xiàn)步驟、應用場景等方面詳細解析其實現(xiàn)方式,需要的朋友可以參考下
    2025-06-06
  • 基于SpringBoot整合oauth2實現(xiàn)token認證

    基于SpringBoot整合oauth2實現(xiàn)token認證

    這篇文章主要介紹了基于SpringBoot整合oauth2實現(xiàn)token 認證,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • java -jar example.jar 產(chǎn)生的日志輸出到指定文件的方法

    java -jar example.jar 產(chǎn)生的日志輸出到指定文件的方法

    這篇文章給大家介紹java -jar example.jar 產(chǎn)生的日志輸出到指定文件的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,感興趣的朋友一起看看吧
    2025-08-08
  • spring boot設置過濾器、監(jiān)聽器及攔截器的方法

    spring boot設置過濾器、監(jiān)聽器及攔截器的方法

    這篇文章主要給大家介紹了關于spring boot設置過濾器、監(jiān)聽器及攔截器的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用spring boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-04-04
  • Java 動態(tài)代理原理分析

    Java 動態(tài)代理原理分析

    這篇文章主要介紹了Java 動態(tài)代理 原理分析的相關資料,希望通過本文能幫助到大家,讓大家掌握動態(tài)代理的原理,需要的朋友可以參考下
    2017-10-10

最新評論

宽城| 聂荣县| 九寨沟县| 新竹县| 庆云县| 镇巴县| 哈密市| 博兴县| 阿合奇县| 偏关县| 黎平县| 巫山县| 文山县| 滦南县| 漾濞| 江口县| 英山县| 茶陵县| 固镇县| 天台县| 静安区| 台东县| 巴楚县| 南阳市| 阜平县| 高雄市| 平塘县| 虎林市| 拉孜县| 海兴县| 永靖县| 翁牛特旗| 自贡市| 芷江| 略阳县| 咸宁市| 博白县| 姚安县| 台南县| 肥东县| 韶关市|