OLTP処理にフォーカスした汎用RDBMS
Greenplum DBはビジネスインテリジェンス(BI)や分析処理に適したシェアードナッシングMassively Parallel Processing (MPP)アーキテクチャを採用しています。一方で、こんにちの汎用リレーショナルデータベース(RDB)の大半はオンライントランザクション処理(OLTP)に最適化されています。汎用RDBはデータウェアハウスやBIアプリケーションへの対応を謳っているため、ユーザーは当たり前のこととしてこのアーキテクチャを使っています。しかしながら、BIや分析アプリケーションのワークロードはOLTPのワークロードとは根本的に異なるため、本来その処理に適したアークテクチャが用いられるべきなのです。
OLTPトランザクションのワークロードでは、速いレスポンスと小さな単位のレコードの更新性能が求められます。このような処理は、単一もしくは少数の並列処理ユニットを使ってディスクの局所的な部分に限定してアクセスが行われるのが一般的です。処理ユニットが単一の大容量ディスクとメモリを共有するシェアードエブリシングアーキテクチャでは、このようなOLTPワークロードを非常に効率的に処理します。また、Oracle RACは共有ディスクを介して一貫性を保ちつつ、複数サーバでクエリを分割して独立に処理できるため、OLTPに対して優れた性能を発揮します。
BI/分析アプリケーションで必要とされる処理能力とは
しかし、BIや分析アプリケーションのワークロードの大半を占める、フルテーブルスキャン、複雑なテーブルジョイン、ソート、集計などの処理を膨大なデータに対して行う場合、シェアードエブリシングアーキテクチャでは大きな困難を伴います。
このようなワークロードでは対象データが増えるに従って指数関数的に処理量が多くなります。処理量の増加に対応するためには、高速なCPUへの置き換え、CPUコア数の増加、メモリの大容量化、高速なストレージ(SSD)の追加などのスケールアップのアプローチが必要になります。しかしながら、このような方法では投資に見合った性能の向上が得られません。
そこで、このような課題に対応するために登場したのがシェアードナッシングMPPアーキテクチャです。このアーキテクチャにおいては、全データは完全に分割されて複数ノード上のディスクに格納され、各処理ユニットはそれぞれの部分データを所有・管理する自己完結したDBMSとして振る舞います。システムは自動的にデータを分散し、全てのハードウェアでクエリのワークロードを並列に処理するようにコントロールします。データを分割することにより全体で必要な計算量を抑えつつ、相対的にコストの小さい処理ユニットを追加することで処理量の増大にも対応することができるようになります。
もちろんRDBMSの処理の並列化はそれほど簡単ではありません。ACID属性を保証しつつ、ボトルネックのない形でシステムをスケールアウトさせていくためには、様々な技術上の課題を解決する必要があります。例えば、効率的な並列実行を可能にするクエリ実行プランを生成するアルゴリズムが必要ですし、複数のユニット間でのデータ移動を最適化することも重要です。シェアードナッシングMPPアーキテクチャの発展の過程で、これらの課題は徐々に解決され、実用的な技術として利用できるようになりました。
Greenplum DBのシステム構成
ここで、Greenplum DBのシステム構成を見ていきましょう。Greenplum DBのシェアードナッシングアーキテクチャでは、データはセグメントという単位で分割されてそれぞれが独立したRDBMSプロセスで管理されます。システム内に複数用意するセグメントサーバと呼ばれるサーバはそれぞれが1つもしくは複数のセグメントを収容し、高い帯域幅で接続されたディスクにデータを格納します。クライアントから発行されたクエリは、システム内に1つだけ存在するマスターサーバと呼ばれるサーバで受け付けられ、システム構成やデータ配置などの情報をもとに効率的に並列実行がなされるようにクエリ実行プランが生成されます。実行プランは各セグメントサーバに送られ、セグメントサーバは並列にすべてのディスク接続を最大限活用しながら処理を実行し、なおかつネットワークインターコネクトを介して必要なデータがやり取りされます。最終的に処理結果はマスターサーバに集約されクライアントに返されます。
Greenplum DBは完全なソフトウェア製品であるため、汎用のx86アークテクチャサーバやネットワークスイッチを使用してシステムを構成します。システム全体で最大限の性能を発揮させるには、ハードウェアの構成のバランスが重要なポイントになります。上で述べたように、高いI/O帯域幅を確保するために数台~十数台のサーバ内蔵ハードディスクを接続したり、高速なセグメントサーバ間の通信を行うためにギガビットもしくは10ギガビットイーサーネットを二重で接続したりするのが一般的です。
性能がスケールアウトするしくみ
シェアードナッシングアーキテクチャにおいては、その名前が示す通りサーバ間のデータの共有はなく、処理は各サーバで独立して実行されます。一般的には各サーバは高いI/O帯域幅を持つローカルディスクに接続するように構成されるため、バックプレーンのSAN接続の共有ストレージに対するアクセスの輻輳に引っ張られることなく、最大限にハードウェアの能力を生かしきることができます。そのため、BIや分析アプリケーションのようなワークロードでは、ノードを増やした分だけ性能がスケールしていきます。
データの分散と並列スキャン
それでは、効率的な並列処理を行わせるために、ユーザーは何か特別な考慮をする必要があるのでしょうか。Greenplum DBでユーザーが考慮すべきことはただ一つ、テーブル定義の際に1つまたは複数のカラムを「ハッシュ分散」キーとして指定することです。このテーブルに対してデータの各行が挿入される際に、システムは指定されたカラムの値からハッシュ値を計算し、これをもとにどのセグメントサーバにそのデータを配置するかを決定します。ハッシュ分散キーの選び方にもよりますが、たいていのケースでは結果としてすべてのセグメントサーバに渡って均等にデータの各行が格納されるはずです。
--ハッシュ分散キーの指定 CREATE TABLE products ( product_no integer, name text, price numeric ) DISTRIBUTED BY (product_no);
一旦このようにシステムにデータが入ってしまえば、データベースシステムが効率的な並列処理を自動で行ってくれるので、ユーザーは意識すること無く汎用RDBとまったく同じクエリを高速に実行することができます。テーブルスキャンは各セグメントでそれぞれが所有する部分に対して並列で行われるため、シーケンシャルなテーブルスキャンと比較して大幅に短い時間で完了します。ユーザーは性能を向上させるために細かいチューニングに多大な労力をかける必要はもはやなくなります。
インデックスによる高速化
データベース上のテーブル検索速度を向上させる重要な機能の一つとしてインデックスがあります。単一行検索やフィルタリング、グループ化のような処理に対しては非常に効果が高いですが、Greenplum DBでもBツリーインデックス、ビットマップインデックスといった形式をサポートしています。
インデックスはRDBの性能改善のための大変ポピュラーなテクニックであり、業務ロジックに合わせてインデックス設計をとことんまで突き詰めていっている現場も少なくないでしょう。しかしながら、インデックスに代表されるチューニングはどちらかというと労働集約的な作業であることに加え、データや業務ロジックが変われば再設計を求められるという側面もあります。
幸いにもGreenplum DBのようなMPP RDBMSにおいては、サーバを追加することにより性能を比較的容易に向上させることが可能です。インデックスによるピンポイントの性能向上は活用しつつも、複雑な適用は控えて変更に対して柔軟なシステムの設計を考慮することが今後は重要になってくるのではないでしょうか。
マルチレベルテーブルパーティショニングによるI/O削減
大量のデータを1つのテーブルに格納するケースの多いデータウェアハウスシステムにおいては、データベースのテーブルパーティションの機能も性能向上の観点で重要です。巨大なテーブルを日付や値の範囲で小さい単位に分割することにより、不要なディスクアクセスを削減することができます。
Greenplum DBではマルチレベルのテーブルパーティションに対応していますが、これは前述のハッシュ分散キーによるセグメントサーバ間でのデータ分割と合わせて効率的なディスクアクセスを実現します。例えば、1年分のデータを含むテーブルが月単位でパーティションが設定されている場合、各セグメントサーバはそれぞれ月単位に分割されたテーブルを持っています。10月のデータだけが必要なクエリがやってきた場合、各セグメントは10月分だけをスキャンすればよいため、大幅にI/Oアクセスを削減して素早いレスポンスを返すことができるようになります。
次回は、Greenplum DBの大きな特徴の一つである高速データローディングのしくみと、効率的な並列実行を可能にするクエリオプティマイザ、データフローエンジンについて詳細をご説明したいと思います。