qinfengge

qinfengge

醉后不知天在水,满船清梦压星河
github
email
telegram

爆発的に便利なsharding-jdbc分庫分表コンポーネント

最近、異なるチャネルから生じる異なる結果を区別する必要があります。
例えば、Web 端で生成された結果、小プログラムで生成された結果、アプリで生成された結果。実際には、テーブル構造は完全に同じですが、異なる区別を行います。

体験後、大規模プロジェクトでない場合や、データベースの分割とテーブルの分割の重要性が非常に高い場合は、shareding jdbc の使用をお勧めしません。
この技術には問題が多く、ドキュメントも少なく、落とし穴がたくさんあります。
簡単な小プロジェクトでは、mybatis-plus の動的テーブル名プラグインを直接使用すれば十分です。

分表#

最初に考えるのはもちろん分表です。大部分の分表はデータ量に基づいています。MySQL データベースの単一テーブルのボトルネックは周知の事実です。
300W の MySQL は簡単に耐えられます。
600W のデータでは遅延が始まり、最適化で解決できます(テーブル構造、インデックス設計)。
800W〜1000W の優れた DBA の最適化でもボトルネックに直面します。

現在の要求はビジネスに基づく分表であり、すべて自分で分表のロジックを設定する必要があります。

sharding-jdbc#

分庫分表については、SHARDING-JDBCというコンポーネントを避けて通れません。
これは軽量 Java フレームワークとして位置付けられ、Java の JDBC 層で追加のサービスを提供します。クライアントがデータベースに直接接続し、jar パッケージ形式でサービスを提供し、追加のデプロイや依存関係は不要です。JDBC ドライバの強化版と考えることができ、JDBC およびさまざまな ORM フレームワークと完全に互換性があります。
Sharding-JDBC のコア機能はデータのシャーディングと読み書きの分離であり、Sharding-JDBC を使用することで、アプリケーションは透明に jdbc を使用してすでに分庫分表、読み書き分離された複数のデータソースにアクセスでき、データソースの数やデータの分布について心配する必要がありません。

インストール依存関係#

Sharding-JDBC を使用するには、まず pom ファイルに依存関係を追加する必要があります。

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.22</version>
        </dependency>
        <!--mysqlドライバ-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>8.0.23</version>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <!-- sharding-jdbc 分庫分表依存関係-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>

注意が必要なのは、druid を使用する場合、依存関係は druid を使用しなければならず、druid-spring-boot-starter ではないことです。issues

設定ファイル#

インストールが完了したら、設定ファイルに分庫分表の設定とルールを宣言する必要があります。

#以下の設定を追加してbean名のオーバーライドを許可する必要があります。これは後のSQLのテーブル操作に主に使用されます。MybatisPlusはクラス名をテーブル名として使用します。
spring.main.allow-bean-definition-overriding=true

#シャーディング戦略、複数のデータソースはカンマで区切ります。例: ds0,ds1
spring.shardingsphere.datasource.names=ds0

#データソースの内容を設定します。以下のds0は上記で設定したものと同名である必要があります。
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/jk_test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root

#テーブルの位置はどのデータソース(データベース)のどのテーブルにあるかです。以下のtables.inspection_resultのinspection_resultはテーブル名の接頭辞です。
#分表を指定するテーブルを設定します。ここではinspection_resultとinspection_result_homeの2つのテーブルを指定しました。
spring.shardingsphere.sharding.tables.inspection_result.actual-data-nodes=ds0.inspection_result, ds0.inspection_result_home

#inspection_resultテーブル内の主キーcidの生成戦略を指定します。SNOWFLAKEは雪花アルゴリズムです。
#spring.shardingsphere.sharding.tables.course.key-generator.column=cid
#spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

#テーブルのシャーディング戦略
spring.shardingsphere.sharding.tables.inspection_result.table-strategy.standard.sharding-column=id
#ビジネスに基づく分表であり、ここではカスタムの分表戦略です。
spring.shardingsphere.sharding.tables.inspection_result.table-strategy.standard.precise-algorithm-class-name=com.jkkj.config.ResultPreciseShardingAlgorithm

#SQL出力ログを有効にします。
spring.shardingsphere.props.sql.show=true

カスタム分表戦略#

ビジネスニーズを満たすためにカスタムの分表戦略を使用できます。

public class ResultPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
        Long id = preciseShardingValue.getValue();
        if (id < 8000000) {
            return "inspection_result";
        } else {
            return "inspection_result_home";
        }
    }
}

id に基づいて返すテーブル名を判断するだけです。

範囲シャーディング#

私たちが使用している strategy.standard.precise は標準シャーディング戦略を表し、SQL 文中の =、IN のシャーディング操作をサポートします。

考えてみてください。現在のシャーディング戦略は id の大きさに基づいていますが、特定の範囲内のデータをクエリすることは成功するでしょうか?
答えは「できません」。標準シャーディングは範囲クエリをサポートしていませんが、範囲シャーディングを使用できます。

#テーブルのシャーディング戦略
spring.shardingsphere.sharding.tables.inspection_result.table-strategy.standard.sharding-column=id
#ビジネスに基づく分表であり、ここではカスタムの分表戦略です。
# standard.precise-algorithm 標準戦略下のシャーディングアルゴリズムには2つのprecise + rangeが含まれます。rangeはオプションですが、rangeを使用する場合はpreciseと一緒に使用する必要があります。
# 精密シャーディングアルゴリズムクラス名、=およびINに使用されます。
spring.shardingsphere.sharding.tables.inspection_result.table-strategy.standard.precise-algorithm-class-name=com.jkkj.config.ResultPreciseShardingAlgorithm
# 範囲シャーディングアルゴリズムクラス名、BETWEENに使用され、<、<=、>、>=をサポートします。
spring.shardingsphere.sharding.tables.inspection_result.table-strategy.standard.range-algorithm-class-name=com.jkkj.config.ResultPreciseShardingAlgorithm

範囲シャーディングのアルゴリズムがあれば、範囲シャーディングの戦略も必要です。
範囲シャーディングと標準シャーディングは同じ ResultPreciseShardingAlgorithm 実装クラスを使用していることがわかります。
したがって、分表戦略を再度修正し、範囲シャーディングを追加する必要があります。

public class ResultPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer>, RangeShardingAlgorithm<Integer> {

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Integer> preciseShardingValue) {
        try {
            Integer id = preciseShardingValue.getValue();
            if (id < 8000000) {
                return "inspection_result";
            } else {
                return "inspection_result_home";
            }
        } catch (NumberFormatException e) {
            log.error("分表時にid変換異常が発生しました");
            throw new RuntimeException(e);
        }
    }

    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Integer> rangeShardingValue) {
        Range<Integer> valueRange = rangeShardingValue.getValueRange();
//        Integer lowerEndpoint = valueRange.lowerEndpoint();
//        Integer upperEndpoint = valueRange.upperEndpoint();

        log.info("範囲 : {}", valueRange);

        Collection<String> tables = new ArrayList<>();

        if (Range.closed(0, 8000000).encloses(valueRange)) {
            tables.add("inspection_result");
        } else {
            tables.add("inspection_result_home");
        }
        log.info("テーブル: {}", tables);
        return collection;
    }
}

分表の完了#

他のビジネスロジックは変更する必要がなく、inspection_result テーブルをクエリする際、Sharding-JDBC は自動的に 2 つのテーブルをクエリし、組み合わせます。

ShardingSphere
Sharding-jdbc の実戦入門之水平分表(一)
Sharding-JDBC 快速入門(只水平分表)
Sharding-JDBC: 単庫分表の実現
Sharding-JDBC 快速入門
shardingsphere 起動時にエラー Property ‘sqlSessionFactory‘または‘sqlSessionTemplate‘が必要です
Sharding-JDBC 之 RangeShardingAlgorithm(範囲分片アルゴリズム)
Sharding JDBC (四) 分片戦略一:標準分片戦略 StandardShardingStrategy

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。