TOP>企業情報>コラム>技術情報>利用範囲がさらに広がる!Postgres Plus 9.4新機能の全容 Vol.3

利用範囲がさらに広がる!Postgres Plus 9.4新機能の全容 Vol.3

EDB Postgres

商用RDBMSと遜色ない機能を持ち、エンタープライズ用途での採用が拡がるPostgres Plusの最新バージョン 9.4が、PostgreSQL 9.4リリースに追随する形で2015年2月にリリースされました。今回は、OLTP、データウェアハウスなどシステム用途の観点からPostgres Plus 9.4が備えた新機能を検証結果を交えてご紹介します。

Vol.3 システム用途別に見るPostgres Plusの新機能

Postgres Plusの今


Postgres Plusは、PostgreSQLをエンジンとし「パフォーマンス」「セキュリティ」「GUIツール」など多くの分野でPostgreSQLに未実装のエンタープライズ向け機能を強力に補完したRDBMSです。

Postgres Plusは、近年、OLTP系システムを中心に採用機会が増えており、9.2の段階で、図1にあるように参照処理において64CPUコアまでのスケールアップの仕組みが実装されました。これにより、ハードウェアのメニーコア化の時代に沿う形で、データベースサーバに搭載されたCPUの有効利用が可能になりました。また、テーブルデータへのアクセスを行うことなくインデックスを検索するだけで結果を返すIndex Only Scanと呼ばれる機能の実装など商用RDBMSと遜色ない数々の機能が実装されてきました。

図1:9.3までのOLTP系性能向上

図1:9.3までのOLTP系性能向上

さらに図2にあるようにデータウェアハウス(以下、DWH)系の機能も次々と強化されてきており、9.3ではマテリアライズド・ビューがサポートされ、集約、集計といった複雑な検索処理の性能を確保できるようになりました。また、Oracle DatabaseのSQL*Loaderと同様の操作性を持つローダ機能としてEDB*Loaderが提供されていることも商用RDBMSユーザが扱いやすい理由の1つと言えます。

図2:9.3までのDWH系機能の強化

図2:9.3までのDWH系機能の強化

本連載ではこれまで2回(※1)にわたり、エンジンであるPostgreSQL 9.4とPostgres Plus 9.4それぞれの新機能の中からエンタープライズでの利用を想定した注目機能をピックアップしてご紹介しました。

(※1)第1回、第2回の記事は以下URLよりご参照ください。
第1回「エンジンPostgreSQLに組み込まれた注目機能解説」
第2回「Postgres Plus 9.4独自の新機能解説」

今回は少し視点を変えて、Postgres Plus 9.4が備えたOLTP系、DWH系システムに対応する以下の新機能に関し、弊社が実施した検証結果を交えてご紹介します。

・OLTP系機能
 -HugePages対応
 -WALバッファ書き込みの改善

・DWH系機能
 -ハッシュ・パーティション
 -マテリアライズド・ビューの拡張

・リソース管理
 -リソースマネージャ

図3:Postgres Plus 9.4が備えたシステム用途別の新機能

図3:Postgres Plus 9.4が備えたシステム用途別の新機能

大容量メモリ環境下での安定稼働を実現するHugePages対応


皆さんは、IA Linuxサーバ環境下で大容量メモリを扱うアプリケーションで発生する可能性がある事象をご存知でしょうか。

大容量メモリを扱うアプリケーションといえばRBMSが代表的ですが、商用データベースに数十ギガバイト(GB)のメモリ領域を割り当てた環境下でデータベースに対し処理を行っている最中にシステムCPUが高騰し、OSがハングするという事象がこれまでに報告されています。データベース・プロセスは仮想メモリ機構の「ページ・テーブル」を経由して物理メモリ領域にアクセスしますが、1ページのデフォルトサイズは4キロバイト(KB)と設定されているため、例えば、16GBの物理メモリの場合は400万個ものページを管理する必要があります。そのため、複数のデータベース・プロセスから同時にメモリにアクセスする処理が実行され、ページのメンテナンスが必要になるとページを管理するOSプロセスがメモリマッピング処理で遅延を引き起こし、結果としてシステムCPUが高騰、OSがハングしてしまうのです。

実際に共有バッファを16GBに設定し、同時接続2,000セッションという高負荷な環境下で弊社独自のOLTPアプリを継続実行させると、図4のCPU使用率のグラフに見られるように徐々にシステムCPUが高騰し、OS全体がハングした状態になります。また、システムCPUの高騰に連動してスワップアウトも次第に大きくなります。

図4:高負荷環境下でのシステムCPUの高騰

図4:高負荷環境下でのシステムCPUの高騰

この問題を回避するためにLinuxカーネル2.6で登場したのがHugePagesと呼ばれる機能です。HugePagesを利用することで、カーネル・バージョンやハードウェア・アーキテクチャに応じて1ページあたりのサイズを2メガバイト(MB)から254MBまで大きくすることができるため、管理対象のページ数を抑制することができます。またHugePagesで確保したメモリはロックされるため、スワップアウトの対象にならないというメリットもあります。

Postgres Plus 9.4ではhuge_pagesパラメータによりHugePagesで確保されたメモリ領域を利用できるようになりました。パラメータの値は「on」「off」「try」の3種類で、デフォルト値「try」はプラットフォームがHugePagesに対応していれば使用します。OS側の HugePagesの設定値はPostgresデーモンプロセスが利用するメモリサイズを元に以下の手順で算出します。

1.huge_pagesパラメータを設定する前に通常どおりデータベースクラスタを起動し、PostgresデーモンプロセスのIDを確認後、確保しているメモリサイズを確認します。

2.サーバのHugePagesの1ページあたりの初期値を確認します。

3.データベース用にHugePagesで確保するページ数を算出します。

4.OS側のファイルにHugePagesの値を設定し、OSを再起動します。

5.huge_pages=onに変更後、データベースクラスタを起動します。

huge_pagesパラメータを「on」に設定して前述と同様の処理を実行した結果が図5です。設定していない時と比べてCPU使用率は安定しており、メモリのスワップアウトも発生しないことを確認しています。

図5:huge_pagesパラメータの効果

図5:huge_pagesパラメータの効果

弊社ではこれまでPostgres Plusの共有バッファは8GB程度での利用をお客様に推奨していましたが、今回HugePagesの設定が可能になったことで、より大規模なシステムでPostgres Plusが採用されるケースが増えることは間違いありません。

更新処理の性能を確保するWAL書き込みバッファの改善


性能低下のボトルネックとなりうる箇所はいくつかありますが、更新処理が行われた際に履歴が格納されるWALへの書き込み処理もその1つです。WALへの書き込みは更新処理で必ず発生しますが、複数の処理で同じバッファを同時に変更することを防ぐため、対象のバッファは書き込むプロセスによって瞬間的にロックされます。同時接続数が多い場合、この瞬間的に保持するロックで競合が発生し、それが性能低下につながるケースがあります。

Postgres Plus 9.4ではロック制御が改善され、図6のようにWALバッファへの並列での書き込みがより効率的に動作するようになりました。これにより9.3までと比べて更新処理の性能を確保することができます。

図6:WALバッファへの並行書き込み

図6:WALバッファへの並行書き込み

弊社の検証では、Postgres Plus 9.3と9.4の環境下で同一のOLTP処理を実行した際の性能差異を確認しました。図7は同時接続750セッションと1,000セッションの秒間トランザクションの平均値を表したグラフで、9.3では1,000セッションで性能が低下してしまいましたが、9.4ではセッション増加に伴い性能も向上することを確認しています。

図7:9.3、9.4における平均TPS比較

図7:9.3、9.4における平均TPS比較

図8はCPU使用率の推移と待機イベントの結果です。待機イベントとは、内部のどの処理で待機状態となっているかを確認する仕組みで、Oracle Databaseでは性能障害のボトルネックをピンポイントで特定できる機能として広く利用されており、Postgres Plusでは同様の機能(※2)が標準実装されています。

9.3ではユーザCPUが100%になるタイミングがあり、待機イベントをみると2番目に「wal insert lock acquire」というイベントが出ていました。このイベントはWALバッファの書き込みを待機していることを示しており、Postgres Plus側でWALバッファのロック待ちが発生したことにより性能が低下したことが判断できます。一方、9.4ではCPUの使用状況も安定しており、「wal insert lock acquire」のイベントも出ていません。

今回の機能改善によって、同時接続数、更新処理が多い大規模なシステムへの採用拡大が期待できます。

図8:CPU使用率と待機イベントの比較

図8:CPU使用率と待機イベントの比較

(※2)Postgres Plusの本機能は、DRITA(Dynamic Runtime Instrumentation and Tracing Architecture)と呼ばれています。

ハッシュ・パーティションによるデータ細分化


大規模テーブルのデータを小さく分割して格納し、検索処理の高速化や管理の効率化を図るための機能としてパーティションがあります。パーティションの代表的な分割方法として、期間や範囲で分割するレンジ、国や地域などをリスト化してその値を持つデータごとに分割するリストがあり、Postgres Plusではこれまでこの2つのパーティションをサポートしていました。9.4ではもう1つの代表的な分割方法であり、各パーティションにデータを均等に分割するハッシュ(※3)が加わりました。

(※3)ハッシュ・パーティションの機能概要は、2回目の記事をご参照ください。
第2回「Postgres Plus 9.4独自の新機能解説」

今回の検証では、パーティション化されていない通常のテーブルとハッシュ・パーティション・テーブルを用意し、同一検索処理を実行した場合の所要時間とアクセスブロック数の違いを確認しました。尚、ハッシュ・パーティションは4、8、16、32分割の4種類を用意し、図9のグラフはパーティション化されていない通常のテーブルを100とした場合の比率で表示しています。パーティションの細分化に伴ってプルニング機能が効果を発揮し、SQLで必要なパーティションに絞り込まれたアクセスになるため、連動して所要時間が短縮されることを確認しています。レンジ、リストに加えて、今回ハッシュが選択できるようになったことで、アプリケーションに応じて大規模テーブルのデータをより適切に分割・配置できるようになります。

図9:ハッシュ・パーティションの効果

図9:ハッシュ・パーティションの効果

CONCURRENTLYリフレッシュのチューニング要素とは


マテリアライズド・ビューは9.3で実装された機能で、集約や集計など複雑な検索処理のパフォーマンスが求められる場合に広く利用される技術です。

マテリアライズド・ビューのデータリフレッシュは、9.4でも完全リフレッシュのみのサポートとなっていますが、今回CONCURRENTLYオプションの実装によってリフレッシュ中にマテリアライズド・ビューの検索処理が並行で実行できるようになりました。(※4)従来のリフレッシュでは内部でTRUNCATE・COPYが行われるため、Postgres Plusで最も強いロックであるAccessExclusiveLockを保持します。そのため、その他の処理はすべて待ち状態になります。CONCURRENTLYオプションでは、内部でDELETE・INSERTでデータを挿入するため、ロックレベルはAccessShareLockを保持すればよく、これによってSELECT処理が並行で実行できるようになりました。必須条件としてマテリアライズド・ビューへのユニークインデックスの設定が必要になるという点に注意してください。これは、マテリアライズド・ビューへのデータ挿入時に内部的には元々格納されているデータと新しいデータをマッピングする作業が入るのですが、その作業で各行の識別に必要になるためです。

(※4)CONCURRENTLYオプションの特徴、利用方法は、第1回の記事をご参照ください。
第1回「エンジンPostgreSQLに組み込まれた注目機能解説」

PostgreSQL 9.4のマニュアルにはCONCURRENTLYオプションの特徴として次のように書かれており、影響が及ぶ行数が多い場合のリフレッシュはCONCURRENTLYオプションを指定しないほうが高速に完了するとあります。

Without this option a refresh which affects a lot of rows will tend to use fewer resources and complete more quickly, but could block other connections which are trying to read from the materialized view. This option may be faster in cases where a small number of rows are affected.
出典:PostgreSQL 9.4マニュアル

上述のとおり、CONCURRENTLYオプションを指定しない場合はTRUNCATE・COPY、CONCURRENTLYオプションを指定した場合はDELETE・INSERTでのデータ入れ替えとなるため、所要時間の違いは皆さんも概ねイメージできると思います。夜間などアクセスがない時間帯が確保できるシステムでは、その時間帯に従来のリフレッシュで高速にデータの入れ替えができますが、そのような時間帯が確保できないシステムでは、リフレッシュの所要時間が長くなるとしてもCONCURRENTLYオプションを指定することでユーザの処理と並行してデータを入れ替えたいという要望があがるでしょう。

マテリアライズド・ビューには、売上データなどオンライン業務で利用されるテーブルから分析処理に必要なデータを抽出・加工して格納しているため、元となるテーブルデータの更新量に比例してリフレッシュにかかる時間が長くなります。そこで今回の検証では、最も所要時間が長くなる条件として、元テーブルのすべてのデータを一括更新した後にリフレッシュを実行し、CONCURRENTLYオプションの有無による所要時間の違いを確認しました。図10にあるようにCONCURRENTLYオプションを指定した場合は指定しない場合と比べて所要時間が約20倍長くなるという結果になりました。

図10:CONCURRENTLYの有無によるリフレッシュ所要時間の比較

図10:CONCURRENTLYの有無によるリフレッシュ所要時間の比較

CONCURRENTLYの内部処理は、図11にあるように5つのステップで構成されています。

今回それぞれのステップの時間を計測したところ、ステップ2の「重複データの有無を確認」する処理で時間がかかっていることが判明しました。

図11:CONCURRENTLYリフレッシュの内部処理と所要時間

図11:CONCURRENTLYリフレッシュの内部処理と所要時間

そこで、理由を探るため、auto_explain機能を使って処理の実行計画を取得しました。以下は取得した実行計画の一部抜粋ですが、赤色の箇所を見るとデータを並べ替えるソート処理で必要なメモリが確保できずディスクが使用されていたため、処理に時間がかかっていることが判明しました。

ソート処理ではワークメモリと呼ばれる領域が使用されます。work_memパラメータに適切な値を設定することで処理に必要な領域を確保したところ、図12のように今回の検証では25%ほど処理時間が短縮できるという結果が得られました。また、実行計画でSort Methodがquicksort Memoryになっていることからも、メモリ上で処理が行われたことが分かります。

図12:work_memパラメータの調整

図12:work_memパラメータの調整

CONCURRENTLYオプションを指定した場合のリフレッシュは、従来のリフレッシュに比べて所要時間が長いという点は変わりませんが、チューニング要素としてwork_memの調整が可能という点を押さえておいていただければと思います。

リソースマネージャで適切なリソース配分


近年、同一サーバ上で複数の業務処理を並行で実行する環境が増えており、データベース側で処理の優先度を制御する仕組みが必要になるケースがあります。Postgres Plus 9.4に実装されたリソースマネージャ(※5)を利用することでデータベース・プロセスが利用するOSリソースをリソースグループと呼ばれる単位で制御することができます。

リソースマネージャで扱えるリソースは、CPUと共有バッファへの書き込み量の2種類で、特に共有バッファへの書き込み量は、I/Oスループットを制御できるPostgres Plus独特の方法と言えます。

(※5)リソースマネージャの機能概要は、2回目の記事をご参照ください。
第2回「Postgres Plus 9.4独自の新機能解説」

今回の検証では、INSERT処理を行うユーザに対してリソースグループを設定し、処理にかかる所要時間と各リソースの利用状況を確認しました。尚、cpu_rate_limitの値は0.5、dirty_rate_limitの値は10,240と設定し、各パラメータは個別に設定したうえで処理を実行しています。

CPUリソースの制御は、cpu_rate_limitパラメータを設定していない場合はCPUをほぼ100%使い切るのに対して、値を0.5と設定した場合、図13のように処理時間は比例して長くなるものの、設定したとおりCPUの利用が50%抑制されることを確認しています。

図13:cpu_rate_limitパラメータによる制御

図13:cpu_rate_limitパラメータによる制御

また、共有バッファへの書き込み量の制御は、dirty_rate_limitパラメータを設定していない場合は秒間に約16,000キロバイトの書き込みがありましたが、値を10,240と設定するとCPUリソースの制御と同じく、図14にあるように処理時間は長くなりますが、設定値の範囲に抑制されることを確認できています。

図14:dirty_rate_limitパラメータによる制御

図14:dirty_rate_limitパラメータによる制御

今回の基本検証により、リソースマネージャによって処理に対して適切にリソース配分が行えることが確認できました。今後の実用的な利用として、例えば、日中のオンライン業務の時間帯にバッチ処理の実行が必要なシステムで、バッチ処理へ割り当てるリソースを制御しオンライン業務への影響を抑制するいった活用が考えられます。

Postgres Plusの今後


Postgres Plusは、9.3までの機能実装でOLTP系システムでの利用が増えていましたが、9.4の登場でHugePagesの利用やWALバッファ書き込みの改善といった大規模かつ高負荷なOLTP系システムに対応する機能が組み込まれたため、今後さらに採用機会は増えていくと考えられます。また、ハッシュ・パーティションの実装やマテリアライズド・ビューの拡張、そして処理に応じて適切にリソースを割り当てるリソースマネージャの実装により、今後、DWH系や複数の異なる処理が実行される環境下での利用も可能になってきます。

2015年後半にリリースが予定されている次バージョン 9.5では、さらに強力なDWH系機能の実装が計画されています。注目すべき機能の1つとして、SQL処理を複数プロセスで分担して処理の高速化を図る「パラレル・クエリ」の実装が予定されており、その基盤としての機能がすでに9.4でいくつか組み込まれています。もう1つの新機能として「MinMaxインデックス」(※6)(※7)があります。MinMaxインデックスを構成するページはいくつかのグループに自動的に分けられ、インデックスには各グループに含まれている対象列データの最小値と最大値が格納されます。全表走査であるシーケンシャルスキャンでこのインデックスが使われると読み込む必要のないデータをスキップすることができ、処理を高速化します。

また、9.6では「COAST」(※7)と呼ばれる仕組みが実装される予定です。Postgres Plusには、1つのページに入りきらないデータを行単位で外部テーブルに分割して格納する「TOAST」と呼ばれる機能が従来から組み込まれていますが、COASTはこれを列単位で行うというもので、効率のよいデータ圧縮が可能です。大規模データの検索や集計を行うBI処理では特定列のデータのみが大量に必要になることが多いため、MinMaxインデックスやCOASTによってディスクI/Oを削減した参照処理の高速化が期待されています。

OLTPに加え、DWH用途の機能、そしてバイナリJSON型といったNoSQL分野の機能など次々と組み込まれ、多様な処理に対応できるRDBMSとしてのPostgres Plusに今後も是非ご注目ください!

(※6)PostgreSQL 9.5への実装に向けて、MinMaxインデックスからBRINインデックス(Block Range Index)へ名称が変更となっています。(出典:PostgreSQL Global Development Group コアメンバー Magnus Hagander氏へ確認(2015年1月末時点))

(※7)各機能が紹介されたイギリス版 PostgreSQLカンファレンス「PGDay UK 2014」の参加レポートは、以下URLよりご参照ください。
イギリス版PostgreSQLカンファレンス「PGDay UK 2014」参加レポート(前編)
イギリス版PostgreSQLカンファレンス「PGDay UK 2014」参加レポート(後編)

  • Postgres Plus は、EDB Postgres の旧製品名です。


高瀬 洋子(Youko Takase)

株式会社アシスト データベース技術本部

アシスト入社後、Oracle Databaseのサポート業務を経て、2009年よりPostgreSQL、EDB Postgresのサービス立ち上げに参画。「PostgreSQLなら高瀬に聞こう」と社内外から言ってもらえる存在となることを目標に日々活動。2014年4月よりイギリスに拠点を移し、PostgreSQL、EDB Postgresの啓蒙活動と顧客対応の後方支援を担当。

高瀬の紹介記事はこちら

連載記事一覧

関連製品/サービス


Facebookで情報をお届けしています

Facebookでは、アシストの「今」を週3回のペースでお届けしています。「めげない、逃げない、あまり儲けない」を合言葉に日々頑張っておりますので、応援よろしくお願いします。



ページの先頭へ戻る