[Database, Java] Java Scalability with Sharded Database

原文はこちら。
https://blogs.oracle.com/dev2dev/java-scalability-with-sharded-database

ユーザー数、トランザクション数、およびデータが指数関数的に増加しているため、スケーラビリティはJavaアプリケーションにとって非常に重要です。シャーディング(Sharding)は、ハードウェアやソフトウェアを共有しないデータベースのプール全体にデータを分散して複製する方法で、個々のデータベースはシャード(shard)と呼ばれます。Javaアプリケーションは、プールへのデータベース(シャード)の追加や削除により、リニアにスケールアップ・スケール・ダウンできます。

リニアなスケーラビリティを達成することに加えて、シャーディングには他にも多くの利点があります。単一障害点を排除し、故障したシャードを他の動作しているシャードから隔離することで、高いデータ可用性をもたらします。シャードのサイズが小さいほど、クラウドへの展開が容易になります。また、シャーディングは異なる国または地域に異なるデータを配置することができるため、データの主権(data sovereignty)とデータの近接性(data proximity)を可能にします。

シャーディングでは、シャードには同じ列で行のサブセットが異なる表が含まれる水平パーティショニングを使用します。このパーティショニングはシャーディングキー(sharding key)に基づきます。シャーディングでは、優れたパーティショニング戦略を選択することが非常に重要です。良いシャーディングキーは、すべてのシャード間でデータが一様に分散するため、DMLやクエリーがホットシャードを作成せずに公平な分配されます。通常の場合、ユーザーまたはアプリケーションのオブジェクトを一意に識別する表の主キーはシャーディング・キーとして適格ですが、シャーディングキーを複数持つ場合もあります。例えばCustomer_IDはシャーディングキー、REGIONはスーパーシャーディングキーといった具合です。下図は、データが3つのシャードにどのように分配されるのかを示しています。これらのシャードはあわせて1個の論理データベースです。

How to make your Java applications shard aware?

Javaアプリケーションでは、特定のシャードへの接続を確立するためシャーディングキーまたは(あれば)スーパーシャーディングキーが必要です。シャードへのセッションが確立すると、すべてのSQLクエリとDMLを指定されたシャードのスコープ内で実行します。JDK 9の標準Sharding APIは、シャード対応のJavaアプリケーションを開発するためのシャードキーとスーパーシャーディングキーを受け入れます。
ShardingKey (Java SE 9 & JDK 9)
https://docs.oracle.com/javase/9/docs/api/java/sql/ShardingKey.html
ShardingKey (Java SE 10 & JDK 10)
https://docs.oracle.com/javase/10/docs/api/java/sql/ShardingKey.html
例えば、シャードされたデータベースに接続する際にシャーディング・キーとスーパーシャーディング・キーを受け入れるよう、Oracle JDBCドライバとUniversal Connection Pool(UCP)(12.2.0.1以降)は拡張されました。

例としてOracle Shardingをみてみましょう。
Oracle Sharding
http://www.oracle.com/technetwork/jp/database/database-technologies/sharding/overview/index.html
http://www.oracle.com/technetwork/database/database-technologies/sharding/overview/index.html
Oracle Database v12.2.0.1は、Global Data Services(GDS)を使ったシャーディングをサポートしています。シャード・ディレクター(Shard Director)またはGSMリスナー(GSM listener)が、接続要求中に渡されたシャーディングキーに基づいて適切なシャードに接続をルーティングします。シャード・トポロジ(特定のシャードに格納されているシャーディングキーのレンジ・マッピング)は最新にメンテナンスされます。クライアント・サイドの接続プールでは、シャード・トポロジーを取得し、クライアント・サイドにトポロジーをキャッシュするために、シャードへの接続を確立した1個の接続だけが必要です。その後、シャーディングキーを渡して接続を要求すると、接続プールはトポロジ内でそのキーが属するシャードを調べ、正しいシャードへの接続を返します。これが直接ルーティング(Direct Routing)です。例えば、Java接続プールはUCPはシャード・トポロジをキャッシュし、シャードディレクタとして機能します。そのため、UCPを使って構築されたアプリケーションは、シャードの高速パスを取得して、シャード・ディレクターへの追加ホップを節約します。

How to aggregate the data from all shards?

アプリケーションがすべてのシャード間でデータを集約する必要がある場合、シャード・カタログ(Shard Catalog)とも呼ばれるシャード・コーディネータ(Shard Coordinator)に接続して、クロスシャード・クエリ(cross-shard query)を実行できます。シャード・コーディネータまたはシャード・カタログを使用すると、ユーザーはシャーディングキーを指定せずにSQL文を発行できます。コーディネータのSQLコンパイラは、クエリを分析して、複数のシャードによって送信され実行されるクエリ・フラグメントに書き換えます。クエリ処理後、データはコーディネータが集約します。これがプロキシルーティング(Proxy Routing)です。

JDBC APIs for Sharding:

Sharding APIでは、データベースへの接続を確立するためにシャーディングキーを渡す必要があります。シャードされたデータベースに接続するには、次の手順が必要です。
  1. Build the sharding key(シャーディングキーの作成)シャーディングキーを作成して、シャーディングキー値とシャーディングデータタイプを渡してください。SQL DeveloperまたはSQLPlusを使用してシャードされたデータベースに接続し、テスト目的でシャーディング・キーのリストを取得できます。
  2. Build the super sharding key(スーパーシャーディングキーの作成)スーパーシャーディングキーはオプションです。シャードされたデータベースがスーパーシャーディングキーを使用していない場合は、この手順を無視してください。
  3. Getting a connection to the shard(シャードへの接続の取得)シャーディングキーとスーパーシャーディングキーを作成後、シャーディングキーに関連するデータを持つシャードへの接続に成功するために、これらのキーを渡す必要があります。
シャードされたデータベースをテストするためのサンプルコードは、JDBCShardingSample.javaを参照してください。

(訳注)
○○のコードを参照してください、とありますが、原文にもそのコードへのリンクがありません。

注意

JDBC driver 12.2.0.1は JDK9の標準Sharding API をサポートしていません。計画では、将来のデータベース・リリースでサポートする予定です。その代わりに、JDK 8やJDK 9を使うアプリケーションでSharding APIをサポートするため、Oracle JDBCドライバはoracle.jdbc.OracleShardingKeyを使います。

以下のコード・スニペットは、Oracle JDBCドライバを使ってシャードされたデータベースへの接続の確立する例です。
import oracle.jdbc.OracleShardingKey;
import oracle.jdbc.OracleType;
import oracle.jdbc.pool.OracleDataSource;

OracleDataSource ods = new OracleDataSource();
ods.setURL(url);
ods.setUser(user);
ods.setPassword(pwd);

// 1. Build the Sharding Key
Date shardingKeyVal = new java.sql.Date(0L);
OracleShardingKey shardKey = 
  ods.createShardingKeyBuilder()
     .subkey(shardingKeyVal, OracleType.DATE)
     .build();

// 2. Build the Super Sharding Key (Optional)
OracleShardingKey superShardKey =
  ods.createShardingKeyBuilder()       
     .subkey("Customer_Location_US”,oracle.jdbc.OracleType.VARCHAR2) 
     .build();

// 3. Get a connection from the specific shard
Connection conn = ods.createConnectionBuilder()
                     .shardingKey(shardKey)
                     .suerShardingKey(superShardKey)
                     .build();

UCP APIs for Sharding:

UCP Sharding APIはシャードされたデータベースへの接続を確立するためにシャーディング・キーを渡す必要があります。シャードされたデータベースをテストするためのサンプルコードは、UCPShardingSample.java を参照してください。

以下のコード・スニペットは、Oracle Universal Connection Pool (UCP)を使ってシャードされたデータベースへの接続を確立する例です。
import oracle.jdbc.OracleShardingKey;
import oracle.jdbc.OracleType;
import oracle.ucp.jdbc.PoolDataSourceFactory;
import oracle.ucp.jdbc.PoolDataSource;

PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
pds.setURL(DB_URL);
pds.setUser(DB_USER);
pds.setPassword(DB_PASSWORD);
pds.setConnectionPoolName("UCP_POOL");
pds.setInitialPoolSize(5); //Initial connections when the pool is created
pds.setMinPoolSize(5); // Minimum number of connections
pds.setMaxPoolSize(20); // Set the maximum number of connections

// 1. Build the Sharding Key
String email= "test@test.com";
OracleShardingKey shardKey =  
  pds.createShardingKeyBuilder()                
     .subkey(email, OracleType.VARCHAR2)                 
     .build();

// 2. Build the Super Sharding Key (Optional)
OracleShardingKey superShardKey = 
  pds.createShardingKeyBuilder()      
     .subkey("Location_US”,oracle.jdbc.OracleType.VARCHAR2) 
     .build();

// 3. Get a connection to the specific shard
Connection conn = pds.createConnectionBuilder()
                     .shardingKey(shardKey)
                     .suerShardingKey(superShardKey)
                     .build();

Appendix:

シャーディングの解説、シャーディング・キーとしてサポートされるデータ型、新しいシャーディングAPIの詳細は、以下のドキュメントを参照してください。
Oracle® Database JDBC開発者ガイド 12c リリース2 (12.2)
データベース・シャーディングのJDBCによるサポート
https://docs.oracle.com/cd/E82638_01/jjdbc/database-sharding.html
Oracle® Database JDBC Developer's Guide 12c Release 2 (12.2)
JDBC Support for Database Sharding
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/jjdbc/database-sharding.html
Oracle® ユニバーサル接続プール開発者ガイド 12c リリース2 (12.2)
データベース・シャーディングのUCP共有プールの概要
https://docs.oracle.com/cd/E82638_01/jjucp/ucp-database-sharding-overview.html
Oracle® Universal Connection Pool Developer's Guide 12c Release 2 (12.2)
Overview of UCP Shared Pool for Database Sharding
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/jjucp/ucp-database-sharding-overview.html

0 件のコメント:

コメントを投稿