:2004年9月13日RDBのボトルネックを解消する「キャッシング技術」とは?〜ObjectCacheが切り開く新たなデータストア・ソリューション〜RDBの抱えている深刻な問題とは?システム開発の本流がWebアプリケーションに移り、JavaやC#といったオブジェクト指向言語によるビジネスロジックの記述が当たり前になってきたことで、バックエンドのリレーショナルデータベース(以下、RDB)との相性の悪さが深刻化している。問題にされるのはO/Rマッピングにかかる工数の多さで、一説には開発工数の4割はO/Rマッピングに費やされているという。たしかにO/Rマッピングによる開発負荷の増大は大問題である。乱暴な言い方をすれば、開発フェイズでの問題は開発者が「頑張れば」なんとかなるし、これまでもそうやって乗り切ってきたわけだ。見落とされがちなのだが、実はRDBに起因するさらに深刻な問題は、運用フェイズに入ってから露見するパフォーマンス不足である。最新のWebアプリケーションは複雑なビジネスロジックを実装しているから、当然ながらRDBに格納するデータ構造も複雑にならざるを得ない。航空機や列車の経路と運賃を格納するデータ構造であれば、1つの問い合わせに対して複数のテーブルを何重にもジョインする必要があるだろう。これがWebから不特定のユーザーがアクセスするBtoCアプリケーションなら、連休前の予約ピーク時に膨大なアクセスが殺到しRDBのパフォーマンスが追い付かない事態も想定される。開発効率の悪さ、パフォーマンス不足という問題を抱えているRDBであっても、エンタープライズ市場のデータベースとして唯一の選択肢と受け止められているのには、それなりの理由があってのことだ。1つは、耐障害性能の実績である。インスタンス障害やディスク障害に対するリカバリ性能は、RDBを採用する最大の理由だろう。開発者の確保が容易だという人的側面も見逃せない。ハードウェアの進化と低価格化に助けられ、「スケールアウト」という手法でパフォーマンス不足をなんとか切り抜けているのが現状だ。Webアプリケーションの複雑さはさらに進み、トランザクション量の増大も避けられないというのに、これからもずっとRDBだけに頼っていて、不安はないのだろうか。“ObjectCache”はRDBのパフォーマンス問題を解決する究極のソリューションここで紹介するのは、独自のキャッシング技術を使ってRDBのパフォーマンス不足を解消する「ObjectCache」という製品である。バックエンドのRDBとオブジェクト指向言語で実装されたビジネスロジック層の中間で稼働するミドルウェアであるObjectCacheは、RDBの耐障害性能をそのままに、テーブルのジョインやディスクI/Oなどに起因するRDBのパフォーマンス不足を解消する、いわば「いいとこ取り」のアーキテクチャを持っている(図1)。Synchronization)を通してO/Rマッピングを行い、J2EEアプリケーションにはローカルキャッシュされたオブジェクトとして振る舞うObjectCacheが管理するキャッシュ・オブジェクト(ObjectCacheがRDBへのデータ格納を保証しているオブジェクト)は、JavaまたはC++で実装されたビジネスロジックからはインメモリ速度でアクセスできるローカルキャッシュとして存在し、同時にバックエンドのRDBと同期を取ってデータを安全に格納する。この一見矛盾する機能を実現しているのはObjectCache独自のキャッシング技術である。キャッシング技術とは何かディスクアクセスよりメモリアクセスの方が圧倒的に速いことは周知の事実だ。RDBもこの原理を利用して一度アクセスされたレコードをメモリに常駐させるバッファ・キャッシュ機能は持っている。2次元表の状態でメモリに乗っているので、テーブルのジョインは発生するわけだし、RDBから取り出したデータはアプリケーション側でさらにオブジェクトの変数に格納するオーバーヘッドも発生する。それならば、エンティティ・オブジェクト(データベースに格納すべきデータを保持しているオブジェクト)をメモリダンプのイメージでデータベースに格納し、同時にメモリ上にキャッシュしておけばよい、という考え方もある。実は、ObjectCacheのファミリ製品であるObjectStoreは、このような思想で作られたオブジェクトデータベースだ。ObjectCacheは、ObjectStoreのキャッシング技術だけを独立させ、データストアには既存のRDBを利用する機能を追加した製品なのだ。ところで、Webシステムのようなマルチユーザー・アプリケーションにおいて、顧客情報といったデータをローカルメモリにキャッシュする場合、以下の重大な懸念が生じるだろう。RDBと同期を取るために、パフォーマンスが低下しないのか障害発生時に、どうやってデータをリカバリさせるのかトランザクションによるデータの整合性は保たれるのか分散環境で使用できるのかこれらについて、ObjectCacheが提供する「回答」を見ていこう。Architecture)という特許取得済みの独自の管理メカニズムによって、RDBから取得したデータをアプリケーション層のローカルなデータキャッシュにマッピングし、さらにトランザクションやリカバリ、負荷分散といった機能を提供する。パフォーマンスとリカバリ性能の両立アプリケーション層にあるエンティティ・オブジェクトを仮にPersonクラスとしよう。通常ならPersonクラスに更新処理が生じると、その都度バックエンドのRDBとネットワーク越しにセッションを張る。RDB側ではトランザクションを開始し、データ更新のDMLを発行し、コミットが完了した時点でようやくPersonクラスに処理が返る。RDB側の処理がもたつけば、その分だけアプリケーションの実行速度に悪影響を与えるだろう。Synchronization)と呼ばれるレイヤを設けている(図1)。Personクラスの更新はまずDSSのログに書き込まれ、直ちに処理が返る。RDBへの更新データの反映はDSSのログを元に非同期に行われるから、RDB側の更新処理に要する時間やロック取得によるほかのセッションへの影響は、アプリケーション側に及ばない構造なのだ。RDBへの書き込みが完了する前にアプリケーションサーバやネットワークの障害が発生しても、DSSのログからRDBのデータを最新の状態に復旧させるからデータ整合性に問題は生じない。Personクラスが最初に呼び出されると、ObjectCacheはDDSを経由してRDBからデータを取得し、ローカルキャッシュされたオブジェクトにマッピングする。Architecture)という管理機能によって自動化されているので、開発者が特別なコーディングを強いられることはない。この動作は、OSが提供する仮想メモリをイメージすればよいだろう。ObjectCacheでは、実メモリを超えたキャッシュ・オブジェクトは、使用頻度の低いものからローカルディスクに書き込み、使用頻度の高いデータを実メモリ上に配置することで、高いパフォーマンスを保ちつつ、スケーラビリティを提供している。アプリケーションは通常、メモリ上に常駐するPersonクラスからデータを取得すればよいから、テーブルのジョインに起因するパフォーマンス低下は初回アクセスのみに限定される。本来はRDBとのセッションを毎回取得するはずのエンティティ・オブジェクトだが、ObjectCacheを利用することで非エンティティ・オブジェクトと同じアクセス速度が得られるのだ。トランザクションキャッシング技術のパフォーマンス性については理解していただけたと思うが、気になるのはアプリケーション・サーバのメモリ空間に分散しているキャッシュ・オブジェクトは、トランザクションを有効にできるのか、という点だろう。Personクラスは異なるクラスAとBでそれぞれインスタンス化されているとしよう。クラスAでPersonインスタンスを更新した場合、古いデータを保持しているクラスBのPersonインスタンスはデータの整合性を失ってしまう。このような状況にあってもデータの整合性を保持するため、ObjectCacheは独自のロック機能を提供している。上記例では、クラスAのPersonnインスタンスであるpaで更新処理を開始すると、直ちにクラスBのPersonインスタンスpbにトランザクションの開始が通知されロックがかかる。paの更新処理が成功するとpbにもコミットが通知されるが、この時点でpbは更新前のデータを保持しているので、古いデータを捨てて最新のデータを取得する。Control)によって、トランザクションにおける一貫性を維持したまま、あるクライアントキャッシュが更新中であっても別のクライアントキャッシュは並行して読み取りを実行できるというユニークな並行処理制御機能が提供されている。分散環境への対応もちろんアプリケーション内のすべてのキャッシュ・オブジェクトに対してObjectCacheの管理は及ぶのだが、驚くことにクラスタリング構成を取ったアプリケーション・サーバの異なるノード間であっても、このキャッシュ管理機構は有効である。キャッシング技術に加えて、必要なタイミングにアプリケーション・サーバやキャッシュを増設することで、容易にCPUの負荷分散も可能になり、スケーラビリティは格段に向上する(図2)。ArchitectureとDSSアプリケーション・サーバの異なるノードに分散したキャッシュ・オブジェクトであってもトランザクションが有効となるRDB+ObjectCacheが活躍するのはどんなシステムかWebアプリケーションにおいて、RDBのパフォーマンスがボトルネックとなるケースとして、データ項目が非常に多い細かなデータ更新が頻繁に走るデータをリアルタイムで表示するといった傾向が指摘されている。大規模なWebショッピングサイトの代表格であるAmazon.comでは膨大な商品数を抱え、2000万/時間といわれるトランザクションが発生するなかで、在庫数などのデータをリアルタイムでユーザーに表示しなければならない。毎回、RDBへ接続していてはとても処理が追い付かないのは明白だ。Amazon.comはObjectCacheの採用によって、RDBパフォーマンス不足を解消したという。ソフトウェアのWebページに掲載されているので、興味のある方はアクセスしてほしい。記事右上の「関連リンク」に代表的な事例へのリンクを用意している。このような事例に共通しているのは、ObjectCache/ObjectStoreを採用することでデータストアに対する考え方が根本から変わってということだ。データ格納のためのRDB、そしてOLAPやBIなどデータ分析のためのCubeという従来型のデータストアの形態に、キャッシング技術に基づいた新たなデータレイヤが誕生している。RDBはあくまでもデータを安全に保管するためのものと割り切り、高い負荷のかかるアプリケーションに近い位置にはキャッシュ型のデータストアを置くという新たな発想だ。それを実現できるのエンタープライズレベルの製品は、現在のところObjectCacheしかないといえる。情報システムは現在のWebからRFID、情報家電とさらに大量のデータを必要とする時代に進んでいる。開発効率が悪くパフォーマンスにも不安を抱えたRDBの将来性について、真剣に検討するべき曲がり角に来ているのではないだろうか。