データ分割の必要性
大規模データ処理において、以下の問題が発生した場合に分割が必要となります:
- データ量の膨大化
- クエリ性能の低下(20msから指数関数的な増加)
- データベース接続数の不足
分割手法の分類
データベースとテーブルの分割には垂直分割と水平分割の2種類があります。
データベース分割
- 垂直分割:機能単位での分割(例:ユーザー、注文、商品データベース)
- 水平分割:単一データベースの複数インスタンス化(例:User_DB_0 ~ User_DB_n)
テーブル分割
- 垂直分割:使用頻度の低い列を別テーブルに分離
- 水平分割:単一テーブルを複数テーブルに分割(例:User_Table_0 ~ User_Table_n)
適用シナリオ
テーブル分割が必要な場合
テーブルサイズが過大になったとき(ディスクファイルサイズの増大)
データベース分割が必要な場合
接続数不足が発生したとき(例:MySQLの最大接続数4000に対し、40ノード×10接続×10サービス=4000接続)
両方の分割が必要な場合
- 高負荷の書き込み/読み取り環境
- 超大規模データセット
ShardingSphereによる実装
Sharding-JDBCを使用した分割実装例:
依存関係の追加
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>5.3.2</version>
</dependency>
分割ルール定義
spring:
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:sharding-config.yaml
設定ファイル例 (sharding-config.yaml)
dataSources:
primary_ds:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/core_db?serverTimezone=Asia/Tokyo
username: admin
password: secure_pass
rules:
- !SHARDING
tables:
customer_data:
actualDataNodes: primary_ds.customer_${0..9}
tableStrategy:
standard:
shardingColumn: client_id
shardingAlgorithmName: client_hash_mod
shardingAlgorithms:
client_hash_mod:
type: MOD
props:
sharding-count: 10
props:
sql-show: true
分割キーの選択
分割キーの選択には以下の要素を考慮:
- アクセス頻度の分布
- データ均等分散の必要性
- キー値の不変性
ShardingSphereの基本概念
論理テーブル
分割された物理テーブルを抽象化した論理的な名称
物理テーブル
実際に存在する分割後のテーブル実体