ITA Issue Article
ITA Issue 連載 : RDBMSへの過度な依存からの脱却を目指して
スケーラブルなO/Rマッピングの実現手法
第10回 ハードウェアの性能をムダなく使いきるために(最終回)
前回は、並列処理を指向した本連載のO/Rマッピング手法を評価する中で、アプリケーション・サーバ/データベース間で確立するコネクション・プールにリスクを見いだした。このリスクを回避し、スケーラビリティを維持するには、通信プロトコルや永続化装置そのものの見直しが必要になる。連載最終回となる今回は、ペタ・バイト級のデータ量を前提にして、読み/書きの双方を高速化し、処理のリアルタイム性を追求するために拡張したアーキテクチャの概要を述べる。
2009年6月23日更新
スケーラビリティを再考する――超大量のデータを扱う際に考慮すべきこと
前回は、本連載でこれまでに紹介してきたO/Rマッピング手法に内在するリスク評価した結果、アプリケーション・サーバとデータベースの間を常時接続するというアプローチにリスクを見いだした。
最終回となる今回は、そのリスクを回避するために、「O/Rマッピング」というスコープから「データ・アーキテクチャ」にまでスコープを広げて解決策を述べる。すなわち、標準化された通信プロトコルやRDBMSを使うことのぜひにまで立ち戻り、前回想定した要件を満たすすべを考察してみたい。具体的には、まず本節において、前回認識したリスクを踏まえて、大規模な並列/分散処理にまつわる潜在的な課題や考慮すべきポイントを整理する。そして、次節ではそれらを解決すべく、これまでに紹介してきたアーキテクチャに施した拡張の特徴を述べ、最終節では、そのアプローチが現在市販されている製品など既存のアプローチと異なる理由を述べる。
それでは、まず大規模な並列/分散処理にまつわる課題や留意すべきポイントを整理しよう。それらは、次の3つに集約することができる。
(1)分散処理の必然性と、それに伴うオーバーヘッド
(2)シーケンシャル・アクセスとランダム・アクセス
(3)データセンターの運用コスト(空調/消費電力/床面積)
以下に、これらの詳細を説明する。
(1)分散処理の必然性と、それに伴うオーバーヘッド
大量のデータを管理するだけならば、大容量の外部ストレージを用いればよい。また、高速なI/Oが必要なら、廉価なPCを多数並べて“分散キャッシュ”を構築すればよい。読み取りに限定すれば、SSD(Solid State Drive)の使用も候補に挙がるかもしれない。
だが、前回想定した要件を満たすためには、数億件の顧客マスタとのマッチングが必要になり、そのデータ加工のために大量の一時領域を使うことになる。つまり、ランダムな読み書きが高速に行える領域を確保し、規定時間内に処理することが課題となる。
一時領域を確保する場所の問題
これまでに解説してきたアーキテクチャでは、アプリケーション・サーバのメモリ空間に一時領域を求めた。なぜなら、廉価なマシンを並べて確保するメモリは、単位金額当たりに確保できる容量が大きく、データベース・サーバ上で確保するよりも費用対効果が高いからだ。
しかしながら、1台のアプリケーション・サーバ上に確保できるメモリには限りがある。メモリ不足によるスワップを避け、処理の高速化を追求するには、複数台のマシンに処理を分割し、並列に実行しなければならない。また、データベースにおけるI/Oのボトルネックを避けるには、複数台に分割してデータを保持する必要がある※1。
|
すなわち、一時領域を確保し、I/O待ちを減らすには、1つの要求をアプリケーション・サーバとデータベース間の「M対N」の通信によって分散処理することが不可欠なのだ。図1に、I/O待ちを減らし、アプリケーション・サーバ上のメモリに一時領域を確保することを狙った分散処理の概要を示す。
ここで、前回指摘したコネクション・プールが問題になる。アプリケーション・サーバとデータベースとの間の通信を滞りなく行うには、分割したすべてのデータベースに対し、十分な数のコネクションを常時確保しておく必要があるからだ。つまり、データベースの分割度とアプリケーション・サーバ内部の並列度を高めるには、それに応じて多数のコネクションを維持しなければならないのである。
※1 多数のディスクを用いてディスクI/Oを分散しても、筐体内のバスのデータ転送速度が制約となる。インデックスを使ってI/O効率を高めようにも、このインデックスもまた、ディスクに永続化されたデータである。多数のレコードに対するインデックスのサイズは大きく、それがデータベース内のキャッシュに存在しない場合は、使用に際して大量のデータ転送が生じる。さらに、筐体当たりのメモリ容量は、メモリ・スロットの数に制約を受ける。
TCPにおける同期通信の問題
上述したコネクション・プールが必要になる背景には、コネクション型で通信を行うこと、つまりTCPを土台にして通信ミドルウェアが構築されていることがある。
例えば、複数の経路が存在したり、経路上でフレームの衝突や消失が起きる可能性が高かったり、受信バッファを十分確保できなかったりするなど、不安定な通信環境を前提とするのならば、TCPを使うメリットは大きい。
しかし、十分な処理能力を有するサーバ間を広帯域のスイッチング・ハブで接続し、全2重で通信するような場面では、TCPのデメリットが無視できなくなる。そのデメリットとは、「通信ノード間を常に同期する」ということだ。TCPでは、輻輳や通信ロスが多発するかもしれないという“悲観的”な見通しに立ち、応答(ACK)パケットを受信するまで送信を停止する。そのため、通信時間が長くなり、トラッフィクが増加してしまう※2。
※2 イーサネット上の最大フレーム長は通常1,500バイトだが、ネットワークの帯域向上やハードウェアの高速化に伴い、最近では9,000バイト程度のジャンボ・フレームに対応した機器が市場に出始めている。しかし、細かいフレームの送受信を頻繁に繰り返すプロトコルを使用したのでは、ジャンボ・フレームのメリットを享受しづらくなる。
構成管理に関する課題
多数のサーバを用いた分散処理を機能させるには、それらの構成を管理する手法が極めて重要であり、それがシステム全体の性能や可用性に大きな影響を及ぼす。
分散処理に際しては、必要なデータがどこにあるのかを知ることが出発点となるが、データを1個所で管理すれば、構成情報の増大に伴い、それを取得する処理がボトルネックになる。また、データを複数のサーバに分割配置したときは、構成情報をたどる分だけ処理の遅延が生じる。
いずれにせよ、構成情報をいかに小さく管理するかが高速化の鍵となる。少ないメモリ消費で情報を管理しつつも、構成管理で生じた障害がシステム全体の可用性のボトルネックになるのを避けなければならない。









