最近、異なるチャネルから生じる異なる結果を区別する必要があります。
例えば、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