24 データベース・シャーディングのJDBCによるサポート
この章では、次の項でデータベース・シャーディングのJDBCによるサポートについて説明します。
24.1 JDBCユーザー用のデータベース・シャーディングの概要
現在、Webアプリケーションには大量のデータのスケーラビリティに関する新しい課題があります。この問題に共通して受け入れられているソリューションはシャーディングです。シャーディングは、独立したデータベース間でデータが水平にパーティション化されるデータ階層アーキテクチャです。このような構成内の各データベースをシャードと呼びます。すべてのシャードが集まったものが単一の論理データベースで、これをシャード・データベース(SDB)と呼びます。シャードはCPU、メモリー、記憶域デバイスなどの物理リソースを共有しないため、シャーディングは何も共有しないデータベース・アーキテクチャです。
シャーディングはグローバル・データ・サービス(GDS)を使用します。GDSは可用性、負荷、ネットワーク待機時間およびレプリケーション・ラグに基づいて、クライアント・リクエストを適切なデータベースにルーティングします。GDSプールは、レプリケートされたデータベースのセットであり、同じグローバル・サービスを提供します。GDSプールのデータベースは、異なるリージョンにある複数のデータ・センターに配置できます。シャードされたGDSプールにはシャードされたデータベースのすべてのシャードおよびそのレプリカが含まれ、データベース・クライアントには単一のシャードされたデータベースのように見えます。
Oracle Database 12cリリース2 (12.2.0.1)以降、Oracle JDBCではデータベース・シャーディングがサポートされています。JDBCドライバは指定されたシャーディング・キーおよびスーパー・シャーディング・キーを認識し、データが含まれている該当シャードに接続します。シャードに対する接続が確立されると、DML、SQL問合せなどのサポートされているデータベース操作は通常どおりに実行されます。次の項では、このガイドで使用されるシャーディングの用語について説明します。
関連項目:
シャーディング、シャードおよびシャードされたデータベース
シャーディングは、独立したデータベース間でデータが水平にパーティション化されるデータ階層アーキテクチャです。このような構成の各データベースはシャードと呼ばれます。すべてのシャードが集まったものが単一の論理データベースで、これをシャード・データベース(SDB)と呼びます。
シャーディング・キー、複合シャーディング・キーおよびスーパー・シャーディング・キー
シャーディング・キーは、範囲、リストまたは一貫性のあるハッシュによって単一レベルのシャーディングで使用されるパーティション化キーです。すべてのシャーディング・キーは、あわせて複合シャーディング・キーと呼ばれます。スーパー・シャーディング・キーは、範囲またはリストによって最上位レベルのシャーディングの複合シャーディングで使用されるパーティション化キーです。シャーディング・キーとスーパー・シャーディング・キーの両方は、各行が格納されるシャードを決定する1つ以上の列を含めることができます。シャーディング・キーは、VARCHAR2、CHAR、DATE、NUMBER、TIMESTAMP型などにすることができます。
JDBCユーザーの場合、データベースから接続を取得したときにシャーディング・キーおよびスーパー・シャーディング・キーを渡すことをお薦めします。ただし、シャーディング・キーは接続文字列でCONNECT_DATA
の別の属性として指定できます。シャーディング・キーを接続文字列で渡すと、1つのシャードのみへの接続に制限されます。したがって、この方法の使用はお薦めしません。次のコードでは、シャーディング・キーを接続文字列でCONNECT_DATA
の別の属性として指定する方法を示します。
(DESCRIPTION=(…)(CONNECT_DATA=(SERVICE_NAME=ORCL (SHARDING_KEY=…) (SUPER_SHARDING_KEY=...)))
ノート:
データベースで指定されているNLS書式に準拠したシャーディング・キーを指定する必要があります。
複数のシャード問合せ
複数のシャード問合せにより、複数のシャードに格納されたデータにアクセスする問合せとトランザクションをルーティングおよび処理できます。複数のシャード問合せはシャーディング・キーを指定しないで実行されます。複数のシャード操作は、データの単純な集計およびシャード間のレポート作成時に使用されます。
シャード・カタログ
シャード・カタログは、シャードされたデータベースの格納および複数のシャード問合せのサポートに使用される特殊なデータベースです。これは、シャードされたデータベースの集中管理にも役立ちます。
シャード・ディレクタ
シャード・ディレクタは、グローバル・サービス・マネージャ(GSM)の特定の実装であり、SDBに接続するクライアント用のリージョン・リスナーとして機能し、SDBの現在のトポロジ・マップを維持します。ディレクタは、接続リクエストで渡されたシャーディング・キーに基づいて、接続を適切なシャードにルーティングします。
シャード・トポロジ
シャード・トポロジは、特定のシャードに格納されたシャーディング・キーの範囲マッピングです。ユニバーサル接続プール(UCP)はシャード・トポロジをキャッシュできます。これにより、シャードへの接続の確立時にシャード・ディレクタをバイパスできるようになります。したがって、UCPを使用して作成するアプリケーションは、シャードへのファスト・パスが得られます。
チャンク
チャンクは表ファミリの各表の単一パーティションです。これは、シャード間のデータ移行の単位です。
チャンクの分割
チャンクの分割は、チャンクが大きくなりすぎた場合や、チャンクの一部のみを別のシャードに移行する必要がある場合に必要となるプロセスです。
チャンクの移行
チャンクの移行は、データまたはワークロードのスキューが発生したときに、シャード数を変更せずに、チャンクを1つのシャードから他のシャードへ移動するプロセスです。これは、ホット・スポットを回避するために、DBAで開始されます。
再シャーディング
再シャーディングは、データがシャード間に再分散されるプロセスで、シャード数の変化によってトリガーされます。チャンクは、シャード間でチャンクを均等に分散させるためにシャード間で移動します。ただし、チャンクの内容は変化しません。つまり、再シャーディング時に再ハッシュは行われません。
24.2 シャーディング・キーの作成について
シャード認識アプリケーションは、シャードされたデータベースへの接続の確立に必要なシャーディング・キーおよびスーパー・シャーディング・キーを識別して作成する必要があります。これを実行するには、シャード認識アプリケーションでOracleShardingKey
およびOracleShardingKeyBuilder
インタフェースを使用する必要があります。
OracleShardingKeyBuilder
は、データ型が異なる複合キーをサポートするために次のビルダー・メソッドを使用します。
subkey(Object subkey, java.sql.SQLTYPE subkeyDataType)
各サブキーのデータ型が異なる可能性がある複合シャーディング・キーを作成するには、ビルダーでsubkey
メソッドを複数回起動します。データ型は、oracle.jdbc.OracleType
列挙またはjava.sql.JDBCType
を使用して定義できます。
例24-1 シャーディング・キーの作成
次の例は、シャーディング・キーの作成方法を示します。
import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.OracleShardingKey;
import oracle.jdbc.OracleType;
import oracle.jdbc.pool.OracleDataSource;
public class ShardExample
{
public static void main(String[] args) throws SQLException
{
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=myhost)(PORT=3216)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=myservice)(REGION=east)))";
String user="testuser1", pwd = password;
OracleDataSource ods = new OracleDataSource();
ods.setURL(url);
ods.setUser(user);
ods.setPassword(pwd);
// build the sharding key object
Date shardingKeyVal = new java.sql.Date(0L);
OracleShardingKey sdkey = ods.createShardingKeyBuilder()
.subkey(shardingKeyVal, OracleType.DATE)
.build();
Connection conn = ods.createConnectionBuilder()
.shardingKey(sdkey)
.build();
Statement stmt = conn.createStatement();
stmt.execute("... SQL statement here ...");
stmt.close();
conn.close();
}
}
次のコードでは、Stringデータ型とDateデータ型で構成される複合シャーディングの作成方法を示します。
...
Date shardingKeyVal = new java.sql.Date(0L);
...
OracleShardingKey shardingKey = datasource.createShardingKeyBuilder()
.subkey("abc@xyz.com", JDBCType.VARCHAR)
.subkey(shardingKeyVal, OracleType.DATE)
.build();
...
ノート:
-
有効でサポートされているデータ型の固定のセットがあります。サポートされていないデータ型をキーとして使用すると、例外が発生します。次のリストに、サポートされているデータ型を示します。
-
OracleType.VARCHAR2/JDBCType.VARCHAR
-
OracleType.CHAR/JDBCType.CHAR
-
OracleType.NVARCHAR/JDBCType.NVARCHAR
-
OracleType.NCHAR/JDBCType.NCHAR
-
OracleType.NUMBER/JDBCType.NUMERIC
-
OracleType.FLOAT/ JDBCType.FLOAT
-
OracleType.DATE/ JDBCType.DATE
-
OracleType.TIMESTAMP/JDBCType.TIMESTAMP
-
OracleType.TIMESTAMP_WITH_LOCAL_TIME_ZONE
-
OracleType.RAW
-
-
データベースで指定されているNLS書式に準拠したシャーディング・キーを指定する必要があります。
24.3 データベース・シャーディングのサポート用API
Oracle Database 12cリリース2 (12.2.0.1)では、データベース・シャーディングを実装するための一連のAPIが導入されました。次の各項では、これらのAPIについて詳細に説明します。
24.3.1 OracleShardingKeyインタフェース
このインタフェースは、現在のオブジェクトがOracleのシャードされたデータベースで使用されるOracleシャーディング・キーを表していることを示します。
構文
public interface OracleShardingKey extends Comparable <OracleShardingKey>
24.3.2 OracleShardingKeyBuilderインタフェース
OracleShardingKeyBuilder
では、サポートされている様々なデータ型のサブキーを持つ複合シャーディング・キーを作成するためのインタフェースを提供します。このインタフェースでは、新しいJDK 8ビルダー・パターンを使用してシャーディング・キーを作成します。
構文
public interface OracleShardingKeyBuilder
例24-2 シャーディング・キーの作成
OracleDataSource ods = new OracleDataSource();
...
//set datasource properties..
...
OracleShardingKey shardingKey = ods.createShardingKeyBuilder()
.subkey("Customer_Name_XYZ", JDBCType.VARCHAR)
.subkey(94002, JDBCType.NUMERIC)
.build();
24.3.3 OracleConnectionBuilderインタフェース
OracleConnectionBuilder
をユーザー名およびパスワード以外に追加パラメータともに使用して、接続オブジェクトを作成します。接続を作成するには、接続リクエストに含まれている必要があるパラメータごとにビルダー・メソッドをコールし、その後build()
メソッドをコールする必要があります。ビルダー・メソッドをコールする順序は重要ではありません。ただし、同じビルダー属性を複数回適用する場合、最新の値のみが接続の作成時に考慮されます。ビルダーのbuild()
メソッドをコールできるのは、ビルダー・オブジェクトで1回のみです。
構文
public interface OracleConnectionBuilder
例24-3 接続ビルダーの作成
...
OracleDataSource ods=new OracleDataSource();
...
OracleConnection conn = ods.createConnectionBuilder()
.shardingKey(shardingKey)
.superShardingKey(superShardingKey)
.build();
24.3.4 データベース・シャーディングのサポートのための他の新規クラスおよびメソッド
この項では、データベース・シャーディングのサポートの実装で導入されたその他の新規クラスおよびメソッドについて説明します。
OracleDataSourceクラスの新規メソッド
createConnectionBuilder
およびcreateShardingKeyBulider
メソッドが、データベース・シャーディングのサポート用にOracleDataSource
クラスに導入されました。
OracleConnectionBuilder createConnectionBuilder() throws SQLException;
OracleShardingKeyBuilder createShardingKeyBuilder()
OracleXADataSourceクラスの新規メソッド
createConnectionBuilder
メソッドが、データベース・シャーディングのサポート用にOracleXADataSource
クラスに導入されました。
OracleConnectionBuilder createConnectionBuilder() throws SQLException;
OracleConnectionクラスの新規メソッド
setShardingKeyIfValid
およびsetShardingKey
メソッドが、データベース・シャーディングのサポート用にOracleConnection
クラスに導入されました。
boolean setShardingKeyIfValid(OracleShardingKey shardingKey, OracleShardingKey superShardingKey, int timeout) throws SQLException;
void setShardingKey(OracleShardingKey shardingKey, OracleShardingKey superShardingKey) throws SQLException;
OracleXAConnectionクラスの新規メソッド
setShardingKeyIfValid
およびsetShardingKey
メソッドが、データベース・シャーディングのサポート用にOracleConnection
クラスに導入されました。
boolean setShardingKeyIfValid(OracleShardingKey shardingKey, OracleShardingKey superShardingKey, int timeout) throws SQLException;
void setShardingKey(OracleShardingKey shardingKey, OracleShardingKey superShardingKey) throws SQLException;
24.4 JDBCシャーディングの例
次のコードでは、JDBCシャーディングAPIの使用方法を示します。
例24-4 JDBCシャーディングの例
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=myhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename)))");
ods.setUser("hr");
ods.setPassword("hr");
// Employee name is the sharding Key in this example.
// Build the Sharding Key using employee name as shown below.
OracleShardingKey employeeNameShardKey = ods.createShardingKeyBuilder()
.subkey("Mary", JDBCType.VARCHAR)// First Name
.subkey("Claire", JDBCType.VARCHAR)// Last Name
.build();
OracleShardingKey locationSuperShardKey = ods.createShardingKeyBuilder() // Building a super sharding key using location as the key
.subkey("US", JDBCType.VARCHAR)
.build();
OracleConnection connection = ods.createConnectionBuilder()
.shardingKey(employeeNameShardKey)
.superShardingKey(locationSuperShardKey)
.build();