オラクルのアーキテクトが教える、Oracle Coherenceの能力をフルに引き出すアーキテクチャ設計のポイント──Oracle DBA & Developer Day 2013レポート

Oracle Java & Developers編集部
2014-01-14 11:00:00
  • このエントリーをはてなブックマークに追加

大規模キャッシュ基盤などとして、さまざまなシステムで活用が進む「Oracle Coherence」。その能力を最大化するためのアーキテクチャ設計のノウハウを、オラクルのアーキテクトが語った。

さまざまなシステムで効果を発揮するOracle Coherence。その実践的な活用ノウハウをオラクルのアーキテクトが直伝


日本オラクル コンサルティングサービス統括 テクノロジーコンサルティング統括本部 テクニカルアーキテクト本部 ミドルウェアアーキテクト部 シニアコンサルタントの古川拓也氏

 Oracle Coherenceは、複数のマシンのメモリ空間を仮想的に統合し、膨大な量のデータを高速かつ効率的に処理することのできるメモリグリッド製品だ。一般には分散キー・バリュー・ストア(KVS)に分類される製品だが、障害発生時でもデータを失うことのない高い可用性を実現する機構が盛り込まれているほか、分散データ処理のための仕組みを提供するなど、他の分散KVSにはない特徴を備えている。単一障害点(SPOF)や単一輻輳点(SPOB)が発生せず、高速な障害検知を可能にする独自のクラスタ管理プロトコルを採用していることも大きな強みだ。

 こうした特徴を生かして現在、国内外の多くの企業が、さまざまなシステムでOracle Coherenceを活用している。2013年11月に日本オラクルが開催したカンファレンス「Oracle DBA & Developer Day 2013」のセッション「Coherence: 実際に使われた実装/アーキテクチャとその選択された理由」では、そうした企業の技術者に向けて、Oracle Coherenceを用いたシステム構築に関する実践的なノウハウが披露された。セッションで講師を務めたのは、日本オラクルの古川拓也氏(コンサルティングサービス統括 テクノロジーコンサルティング統括本部 テクニカルアーキテクト本部 ミドルウェアアーキテクト部 シニアコンサルタント)である。

Filter処理でValue内のデータを使って値を取得する際にはインデックスを作る

 古川氏が初めに紹介したノウハウは、「OLTPにおける、Keyに入っていないデータを使った値の取得」に関するものだ。

 Oracle Coherenceは、他の分散KVSと同様に「Key」と「Value」でデータを管理している。基本的にはKeyを指定して、それにひも付けられたValueを取得するのがデータ・アクセスの基本であり、古川氏も「真価を発揮するのはKeyを指定してのデータ・アクセス」と明言する。

 ただし、システムによっては、Valueの中にあるデータを条件にして別のデータを抽出したいという場合もあるだろう。例えば、Keyに商品名、Valueにその金額を格納しており、ある金額以上の商品だけをリストアップするといったケースだ。そうした目的のためにOracle Coherenceが提供しているのが「Filter処理」という仕組みである。

 FilterはKey以外の値を使ってデータを検索する機能であり、クラスタを構成する各マシンのJVM上で条件に合致するデータをパラレルに抽出することによって実現している。なお、Oracle Coherenceではインデックスを作成することも可能であり、条件に合ったインデックスを事前に作っておけばFilter処理を高速化できる。古川氏は、このインデックスの作成がFilter処理を使う際のポイントだと話す。

 「インデックスを作らない場合、各JVMは自身が管理しているデータを1件1件チェックすることになり、場合によってはリソースを大量に消費します。そのため、Filter処理はインデックスを作成したうえでお使いいただくのがベスト・プラクティスになります」(古川氏)

Value値によるデータ取得で秒間のトランザクション処理数が多い場合は逆引きキャッシュを作る

 古川氏が、Filter処理に関するもう1つのポイントとして挙げたのは、1秒当たりのトランザクション処理件数(TPS:Transaction Per Second)が多くなった場合の対処法だ。Keyを指定したデータ・アクセスであれば、該当するデータを持つJVMだけが応答すればよい。しかし、Filter処理ではクラスタを構成する全JVMにリクエストが発行され、すべてのJVMがリクエストに対応するための処理を行う。つまり、いくらマシンの数を増やしても、Filter処理に限って言えばスケールアウトしないことになる。このため、特にトランザクション量が多い用途でFilter処理を使うと、十分なパフォーマンスを得られない可能性が出てくる。

 とは言え、業務要件によっては、たとえトランザクション量が多くてもFilter処理を使いたいというケースがあるだろう。そこで古川氏が対応策として紹介したのが、「逆引きのキャッシュを作る」という方法だ。氏は例として、「KeyとしてユーザーID、Valueにメール・アドレスとパスワードを入れており、ユーザーIDとメール・アドレスの両方でユーザー認証を受け付けたい」といった場合の対応例を紹介した。

 「まず、正規のKey/Valueの組み合わせのほかに、メール・アドレスをKey、ユーザーIDをValueにした逆引きのためのキャッシュを作成します。そして、メール・アドレスで認証を行う際には、作成した逆引きキャッシュに対してメール・アドレスをKeyにしてValueのユーザーIDを取得します。続いて、正規のKey/Valueに対してユーザーIDをKeyにしてアクセスすれば、パスワードを取得することが可能となり、Filter処理を使わなくても同様の仕組みを実現できるわけです」(古川氏)

トランザクション処理やオブジェクトの部分更新はインプレース・プロセッシングで性能を確保

 続いて古川氏が紹介したのは、「インプレース・プロセッシング」の活用ノウハウである。

 インプレース・プロセッシングとは、Oracle Coherenceが保持するデータに対し、Oracle Coherence側で処理を行うための仕組みだ。その目的から用意されているのがEntryProcessorと呼ばれるインタフェースであり、これを使うことで値の加算や乗算、更新といった処理や、カスタマイズした独自の処理を実行できる。Oracle Coherence上で処理が完結するため、「値の更新」などの処理をアプリケーション側で行うよりもスマートに実装できる点がメリットとなる。

 このEntryProcessorの具体的な使いどころとして、古川氏はトランザクション処理を一例に挙げる。

 「トランザクション処理において、愚直にロックを使った実装では、アプリケーション側でロックを取得したうえで値を取り出し、それを更新したOracle Coherenceに格納して、その後にロックを解放するという手順となり、ロック時間が長くなります。

 一方、EntryProcessorを使えば、Oracle Coherence側で処理が完結し、ロック時間を短くすることができます。これによってロック競合が減り、システム全体のパフォーマンスを高められるのです。Oracle Coherenceでこうしたアトミックな処理を行う際には、ぜひEntryProcessorを活用してください」(古川氏)

 また古川氏は、オブジェクトを部分的に更新するといった処理にもEntryProcessorが有効だと説く。例えば、分割されたデータをOracle Coherenceの特定のオブジェクトに次々に追加するようなケースだ。通常であればOracle Coherenceからオブジェクトの全フィールドをいったん取り出し、データを追記したうえで書き戻すといった流れになるだろう。しかし、EntryProcessorを使えば、Oracle Coherence側でデータの追記処理を行えるので、アプリケーション側では単に追記したいデータを送るだけでよい。これにより、処理時間の短縮や負荷軽減を図れるというわけである。