「データのライフ・サイクル」で考えるHadoopの使いどころ
定型処理と非定型処理
コンピュータ・システムの導入の歴史は、人間が行っていた定型処理を自動化していく歴史でもありました。例えば、給与計算や売上集計などは、定型処理の代表です。
定型処理は、決まったルールにしたがって厳密な計算を行うことが求められるため、コンピュータによる自動化に非常に向いていました。コンピュータ・システムの利用が、計り知れないほどの生産性向上をもたらしたことは、皆さんがご存じの通りです。
RDBMSの特徴は、定型処理の自動化に最適化されていること、と見ることができます。現在でも、コンピュータ・システムで代替されていない定型処理があちこちで見られますので、「定型処理の自動化」という流れは今後も続くでしょう。
しかし、すでに定型処理のほとんどを自動化してしまった分野では、さらに生産性を向上するため、非定型処理のためのコンピュータの活用にも目が向けられます。マーケティングにおけるデータ・マイニングは、その代表例です。
例えば、レジから収集される過去のPOS(販売時点管理)データから、よく一緒に買われる商品を見つける、といった分析が行われています。書籍販売サイトでは、過去の販売履歴をもとに「この本を買った人は、こんな本も読んでいます」というお薦めが行われて、売り上げ増に役立っています。
非定型処理には、絶対的な正解というものは存在しません。よく一緒に買われる商品を同じ場所に配置しても売上が増える保証はありませんし、お薦めされた本に興味があるかどうかは、人によって異なります。しかし、非定型処理をうまく活用した企業の成功事例によって、有用性は広く認識されています。
データ・マイニングなどの非定型処理の特徴は、以下のように整理できます。
- どのような分析が必要になるか予想できない
- 分析結果を最終的に解釈するのは人間なので、正しい解釈ができるように、システムとしてさまざまな種類の分析が可能になっていることが求められます。また、分析結果を見た上で、条件を変えてもう1度分析の処理を実行することも、頻ぱんに行われます。つまり、どのような分析がなされるかをあらかじめ予想することが難しくなります。
- データ量がどんどん増えていく
- 非定型処理では、ある目的で収集されているデータを、まったく別の目的に活用することがよくあります。例えばPOSデータは本来、売上集計や在庫管理などの定型処理の必要性から収集しています。本来の目的のみに使うのであれば、集計が終われば、削除しても差し支えありません。しかし、マーケティングというまったく別の目的に活用するためには、過去のデータの膨大な蓄積があることが非常に重要になります。よって、蓄積・処理すべきデータ量が、どんどん増えていきます。
このように、非定型処理に求められるニーズは、定型処理と大きく異なります。非定型処理に求められるニーズは、RDBMSの特徴とは必ずしもマッチしません。
RDBMSのインデックスは「あらかじめ想定される処理を高速化する」ことに効果を発揮します。しかし、非定型処理では、どのようなクエリーが実行されるかを予想しづらいため、インデックスによる高速化が難しくなります。
また、RDBMSのデータベースにインデックスを作成するには、ある程度の計算コストがかかります。この計算コストは、レコード数が増えるほど大きくなるので、多くの業務システムでは、要らなくなった過去のレコードをデータベースから削除するという運用が行われています。しかし、過去に蓄積された膨大なレコードを活用したいというニーズがある場合は、簡単に削除するわけにはいきません。
リアルタイム処理とバッチ処理
次に、RDBMSにおけるリアルタイム処理とバッチ処理について考えてみましょう。
リアルタイム処理とは、コンピュータの利用者からのデータ処理要求を即座にこなすタイプの処理です。コンビニATMで現金引き出しの操作をすると、口座残高の確認、残高の差し引きなどのトランザクション処理が瞬時に行われます。RDBMSは、リアルタイム処理に必要な機能をすべて備えています。
一方、バッチ処理は、同じ種類のデータ処理を大量にまとめた「ジョブ」を単位として、一度に処理するものです。バッチ処理をうまく活用し、コンピュータのリソースが空いている時間帯(夜間・早朝など)にまとめて処理することで、システム活用の効率を大幅に改善することができます。RDBMSに格納されているデータに対しても、もちろんバッチ処理を適用することが可能です。例えば、銀行システムでは、公共料金の引き落としや給与振り込み、利率計算などの処理をバッチ処理で行っています。
しかし、バッチ処理によっては、RDBMSの高度な機能を必要としないものもあります。以下に、トランザクション処理機能やインデックス機能を必要としない例を挙げます。
トランザクション処理機能は、同時に複数のユーザーが読み書きするデータを扱う場合には必須ですが、同時の読み書きが発生しないデータを扱う場合は必要ありません。
銀行システムを例に説明します。口座引き落としのバッチ処理の場合、コンビニATMが24時間動いているため、バッチ処理が行われている最中に口座残高が変わる可能性があります。一方、「昨日の取引集計」のバッチ処理の場合は、読み出すべきデータ(すなわち昨日の取引履歴すべて)は過去のデータなので、バッチ処理の最中に書き換わる可能性はありません。バッチ処理が書き出した集計結果データをほかのユーザーが書き換えることもありません。このため、トランザクション処理は必要ありません。
インデックスは、特定のデータのみを読み書きする場合には必須の機能ですが、バッチ処理ですべてのデータを読み書きする場合は必要ありません。
Aさんの口座からB社の口座への振替をリアルタイム処理として行う場合は、巨大なデータベースから「Aさんの口座残高」と「B社の口座残高」のみを取り出して読み書きする必要が生じるため、インデックスが必要になります。一方、「昨日の取引集計」のバッチ処理の場合は、昨日の取引履歴レコードすべてを集めたテーブルを作っておけば、先頭のレコードから順番に読み出していけばいいので、インデックスは不要になります。
これらの高度な機能は、システムをスケール・アウトさせることを難しくする要因となっています。例えば、トランザクション処理を複数台のサーバーでうまく扱うのが難しいことは、「ブリュワーのCAP(Consistency, Availability, Partition Tolerance)定理」として知られています。CAP定理は、コンピュータ・システムの3つの要件、「一貫性(C)」、「可用性(A)」、「分割耐性(P)」を同時に満たすのが不可能であることを説明しています。