分散アプリケーションを設計する際には、可用性とパフォーマンスを考慮する必要があります。一般的なソリューションとしては、クライアント・システムにデータ・ストアを含みます。クライアントは普通、リソースが限定されているため、軽量のデータ・ストアを要求します。ところがこの手法では、異種構成のデータ・ストア間でのデータ同期が難しくなります。この問題に対する一つの解法が、異種構成のデータベース複製にJDBCとSyncML標準を使った、Javaベースのソリューションです。まず少し、背景を説明しましょう。
注意: この記事は、読者がサーバー側のJava技術に慣れており、ソフトウェアのインストールや設定の詳しい説明は不要であることを想定しています。
複製(replication)というのは、2つの環境の間で、データベースの全て、あるいは一部と全く同じものを作るプロセスです。一貫性を保つため、ソース側のデータベースに加えられた変更は、複製されたデータベースに伝達されます。
複製は一方向の場合も、双方向の場合もあります。双方向の複製は、それぞれのデータベースに加えられた変更がデータの競合を起こすこともあるので、はるかに困難です。こうした変更を2つのデータベース間で伝達する時には、一貫性を保つため、相互の違いを調停する戦略が必要になります。
複製に対する基本的な要求として、複製されるべき個々のデータ単位を固有識別する必要があります。また双方向複製では、対応するデータ単位をデータベース間で識別するためのマッピング・スキームも必要になります。
複製の要求内容によって、様々なスキームがあります。一方向複製では、マスター・データベースがデータ単位に対するID生成を行います。双方向複製では、アプリケーションのID生成スキームに基づいて、マッピング・スキームを定義する必要があります。ID生成とマッピング・スキームとしては、各データベースが相互排他的な範囲の数字をIDとして使い、IDを完全一致させる、という単純な方式もあります。もっと複雑な例では、ID生成サービスやデータベース固有のスキームを使い、データベース間でIDマッピングを維持する必要のあるものもあります。
複製プロセスでの次のステップは、どのデータ単位が変更されたかを識別することです。リレーショナル・データベースの場合では、追加的なフィールドを使って、データ単位の状態と状態変化のタイムスタンプを記録します。あるいは、トリガーを使って変更検出プロセスの一部を自動化することができます。テーブルに付加されたInsert/update/deleteトリガーは、データ単位に加えられた変更を検出し、変更ログ・テーブルにおける変更を記録します。そうすれば変更ログ・テーブルを使って、(いつ加えられたものであっても)データ単位に加えられた変更を特定することができます。
複製の最終目標は、一貫性のある、共通データ・セットのコピーを複数作ることです。この目標を実現するには、個々のデータベースで検出された変更を交換し、調停する必要があります。
ここで、困難な設計課題に直面することになります。つまり、下記の選択が必要なのです。
- 交換すべき変更を表現するデータ・フォーマット
- アプリケーションの要求に基づいた、HTTPやFTP、JMSなどのトランスポート機構
- 複製に参加している実体間での交換プロトコル
- データ単位間での競合検出と解決機構
SyncMLは、データ単位の追加、削除、修正にXMLメッセージを使う同期プロトコルを定義しています。また、ノードが認証を行えるように、セキュリティー情報も交換できるようになっています。
Sync4Jは、SyncMLのオープン・ソースJava実装で、複数のトランスポート機構をサポートしています。Sync4Jはまた、アプリケーションの要求に基づいた競合検出や、解決戦略のフレームワークも提供しています。
この記事では、単純なデータ複製の例を、順を追って説明します。この例は、双方とも似た構造の顧客テーブルを持つ異種構成の2つのデータベース間で、顧客データ・レコードの双方向複製を行うものです。複製すべき個々のレコードを識別するために、固有の顧客IDを使います。ここではテーブルに2つのカラムを追加し、各レコードの状態と、最後の状態変化のタイムスタンプを記録します。この例では、状態とタイムスタンプのカラムに中身を入れるのは、手動で、あるいはアプリケーションが行います。先に述べた通り、変更ログ・テーブルに変更データを入れる作業の自動化には、トリガーが適切な手段です。ただし、この例で使われているデータベースには、限定されたトリガー機能しかありません。ですから、この実装では使わないことにしました。また、この例には双方向複製に対する競合解決戦略が入っていません。競合があると、複製プロセスがフェールします。
この記事からダウンロードできるj-sync4j.zipには、ソースとターゲットのデータベースで顧客テーブルを設定するための、SQLスクリプトが含まれています。Sync4Jサーバー・モジュールと複製クライアント用のコードも、このzipファイルに含まれています。
図1は、各ノードとデータベース、またそれらの接続を表したネットワーク図です。
図1. ネットワーク図
Sync4Jサーバーを実行するためのサーバー側の環境をTomcatサーブレット・コンテナー内部に設定し、ソース・データベースとしてDerbyを使います。
また、Sync4Jクライアント・プログラムを実行するためのクライアント側の環境を、HSQLDBをターゲット・データベースとして使って設定します。(この場合では、J2SE SDKとAntもインストールされていることを前提にしています。)
このアプリケーションを実行するためには、TomcatとSync4Jサーバー、そしてデータベース・エンジンという、3つのオープン・ソース・コンポーネントをサーバー側にインストールする必要があります。
TomcatとSync4J、そしてDerbyをインストールする
次のステップに従って、3つの主要サーバー・コンポーネントをインストールします(参考文献にダウンロード・リンクがあります。)
- Tomcat 5.0.29をダウンロードして解凍します。ここではTomcatのインストール・ディレクトリーをTOMCATとします。
- 環境変数J2EE_HOMEをTOMCATに設定します。
- Sync4J Server 4.0.2をダウンロードして解凍します。ここではSync4Jサーバーのインストール・ディレクトリーをSYNC4Jとします。
- Derbyをダウンロードしてインストールします。ここではDerbyのインストール・ディレクトリーをDERBYとします。
次に、この例で使うコードを設定する必要があります。この記事の先頭、または最後にあるCodeアイコンをクリックしてj-sync4j.zipをダウンロードします。この記事で使うクライアントとサーバーのコード、そしてSQLスクリプトを含むダウンロード・ファイルを、一つのディレクトリーに解凍します。ここでは、このディレクトリーをTESTSYNCとします。
DERBY\libにあるdb2jcc.jarとdb2jcc_license_c.jarを、それぞれTOMCAT\common\libとSYNC4J\libにコピーして、JDBCドライバーのクラス・パスを設定します。
Sync4Jサーバーに対するDerbyイントール・スクリプト
次に、ディレクトリーTESTSYNC\derbyをSYNC4J\default\sqlに移動します。
この記事で提供しているスクリプトは、Sync4Jサーバー・ダウンロードに付属している他のデータベース・スクリプトと似ていますが、ここではDerby用に少し修正してあります。
Sync4Jサーバー・モジュールを構築するには、次の手順に従います。
- TESTSYNC\module\build.batにある
SYNCSERVER_DIRを、SYNC4Jを指すように設定します。 - TESTSYNC\module\build.batを実行します。
Sync4Jサーバーを設定するには、次の手順に従います。
- Derbyの中に、sync4jdbという名前のデータベースを作ります。ステップ3のコードの中に記述されているJDBC設定では、DERBYにあるsync4jdbという名前のデータベースが、ユーザー名sync4j、パスワードsync4jで使用できることを想定しています。
- Derbyに付属のIJツールを使って、このデータベースを作成し、設定します(Derbyのツールに関しては参考文献を見てください)。
-
SYNC4J\install.propertiesのプロパティーを下記のように設定します(DERBYを、JDBC設定にある実際のパスで置き換えます)。dbms=derby jdbc.classpath=DERBY/lib/db2jcc.jar;DERBY/lib/db2jcc_license_c.jar; jdbc.driver=com.ibm.db2.jcc.DB2Driver jdbc.url=jdbc:derby:net://localhost:1527/"DERBY/sync4jdb" jdbc.user=sync4j jdbc.password=sync4j modules-to-install=foundation-1.0,pdi-1.1,testsync-1.0
DERBY\frameworks\NetworkServer\bin\startNetworkServer.batを実行し、Derbyをネットワーク・サーバーとして起動します。
Derbyをネットワーク・サーバーとして起動するための方法に関しては、Derbyのマニュアル(参考文献)を見てください。
IJツールを使ってTESTSYNC\create_table_server.sqlを実行し、Derbyデータベースにcustomer1というテーブルを作ります。
TomcatでSync4Jサーバーとサンプル・モジュールをインストールする
Tomcatサーバー用にSync4Jサーバーをインストールし、Sync4Jデータベースを設定するには、次の手順に従います。
- SYNC4Jから
SYNC4J\bin\install.cmd tomcatを実行します。 - 画面の指示に従ってYを押し、testsync-1.0モジュール用のデータベースを再構築します。
Tomcatサーバーを起動するには、SYNC4JからSYNC4J\bin\sync4j-tomcat.cmdを実行します。
これでサーバー側の設定が終わります。今度はクライアントをインストールします。
クライアント側に、データベース・エンジン、HSQLDBをインストールする必要があります。その後で、サンプル・コードをインストールして設定します。
クライアント・アプリケーションのデータベースを設定するには、次のステップに従います(参考文献にダウンロードへのリンクがあります)。
- HSQLデータベースをダウンロードして解凍します。ここではHSQLデータベースのインストール・ディレクトリーをHSQLDBと呼ぶことにします。
- HSQLを、testという名前のデータベースを持つネットワーク・サーバーとして起動します。
- TESTSYNC\create_table_client.sqlを実行し、HSQLデータベースの中に、先と同じようなテーブル(customer2)を作ります。
- HSQL JDBCドライバー、HSQLDB\lib\hsqldb.jarをTESTSYNC\client\libにコピーします。
-
TESTSYNC\client\config\spds\sources\testsync.propertiesにある、クライアントのJDBCプロパティーを下記のように設定します。jdbcDriver=org.hsqldb.jdbcDriver urlConnection=jdbc:hsqldb:hsql://localhost/test
- ユーザー名とパスワードを正しく設定します。
次にTESTSYNC\client\build.batを実行し、クライアント側のアプリケーションをビルドします。
Derbyデータベース中のcustomer1にレコードを挿入します。例えば、
insert into customer1 (userid, password, cl_op_type, clo_op_time)
values ('user1', 'pass1', 'N', CURRENT_TIMESTAMP);
|
HSQLデータベース中のcustomer2にレコードを挿入します(useridは、customer1にあるレコードとは必ず異なる値を持つようにします)。例えば、
insert into customer2 (userid, password, cl_op_type, clo_op_time)
values ('user2', 'pass2', 'N', CURTIME()); |
TESTSYNC\client\output\testsync.batを実行します。
これで、customer1テーブルはcustomer2に挿入されたレコードを持ち、またcustomer2はcustomer1からのレコードを持っているはずです。
この記事では、汎用のデータベース複製ソリューションの設計に関して、主な概念と問題点について説明しました。メモリー要求の小さい埋め込みのデータベースは、高度な分散アプリケーションを設計する上での重要な選択肢となり、また異種構成のデータベースも可能となります。複製プロセスと、それに関連した問題点をよく理解しておくことで、そうしたシステムの設計が改善されることになります。この記事で取り上げた双方向複製の例に対して競合解決戦略を持たせ、またレコードの変化データを自動記録させるように、ぜひ拡張してみてください。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Sample code | j-sync4j.zip | 658KB | HTTP |
- SyncMLは、あらゆるデバイスやアプリケーションを任意のネットワーク経由で同期させるための共通言語です。この標準について、OMAのSyncML Web pageでさらに学んでください。
- この記事で取り上げているソフトウェアの最新版を入手してください。
- Lance D. Bader著による「Integrating Cloudscape and Tomcat」(developerWorks, 2002年11月)は、CloudscapeとTomcatの設定方法を詳細に説明しています。
- SyncMLプロトコルの初心者であれば、Chandandeep Pabla著の「SyncML intensive」(developerWorks, 2002年4月)を読んでください。
- Aashish Patil著による「Sync traps」(developerWorks, 2001年9月)を読んで、同期プロセスについて学んでください。
- developerWorksのJava technologyゾーンには、Java開発者のための資料が他にも豊富に取り揃えられています。
-
Developer Bookstoreには、Java関連の書籍を始め、広範な話題を網羅した技術書が取り揃えられていますので、ぜひご覧ください。