PostgreSQL導入に向けての取り組み ~大規模システムへの適用を目指して~ (2)
3.1.1 処理性能と安定性 - ver. 8.2 -
PostgreSQL 8.2 で長時間運転安定性検証を行った結果を示します。 (なお、検証条件や環境については 図3.1.1-1 をご覧ください。) 8.2 では autovacuum の有効性を確認するための検証を行いました。
図3.1.1-2 | 図3.1.1-3 |
図3.1.1-2 は autovacuum を OFF にした時、図3.1.1-3 は autovacuum を ON にした時のスループットの変化を表しています。 autovacuum を OFF にすると、時間が経つにつれて不要領域が増加するため、徐々に性能が低下しています。
VACUUM は性能の低下を抑制するために実行すると先程説明しましたが、図3.1.1-3 のグラフにありますように、 autovacuum を ON にして VACUUM が実行されても性能の低下が抑制できませんでした。
これは、PostgreSQL 8.2 の autovacuum の仕様に問題があるために起こっていた現象でした。 PostgreSQL 8.2 の autovacuum は複数のテーブルに対して、パラレルに VACUUM が実行できないため、一旦大きなテーブルに VACUUM が実行されると、 そのテーブルの VACUUM が終了するまで、他のテーブルへ VACUUM が実行できません。 そのため、VACUUM が必要なテーブル(autovacuum の閾値(しきいち)を越えたテーブル)であっても VACUUM が実行できずに、結果として不要領域が増加してしまうためです。
上記の検証結果から、PostgreSQL 8.2 をシステムへ適用する際には以下の 2 点を検討ポイントとしました。
- 検討ポイント1:テーブル単位で適切な VACUUM を実行する時間帯を検討する事
-
autovacuum は使用せず、業務の閑散期を狙って cron 等でユーザが VACUUM を実行するようにします。 ただし、次の VACUUM 実行までに生成される不要領域による性能低下がシステムの許容範囲内の値であるかを、予め検証等を行い確認しておく必要があります。
更新の発生しないテーブル(VACUUM 実施対象外のテーブル)には、半年に 1 回等、 定期メンテナンス作業という位置づけで VACUUM を実行し、XID の周回問題を回避する必要があります。
- 検討ポイント2:テーブルの断片化対策を検討する事
-
半年に 1 回等、定期メンテナンス作業という位置づけで「CLUSTER + ANALYZE」を実行してテーブルとインデックスの断片化 (インデックスの場合は B-Tree の段数が増えてしまった事を解消できる場合もあります)を解消し、性能を回復させます。
以上のように、PostgreSQL 8.2 をシステムに適用するための 2 つの検討ポイントを導き出しました。 しかし、業務の閑散期は「バッチ処理(バックアップや収集データの分析処理、データ投入)」が稼働するシステムが多かったため、 VACUUM の実行時間の確保が困難なケースが多く、ほとんどは適用に至りませんでした。
3.1.2 処理性能と安定性 - ver. 8.3 -
PostgreSQL 8.3 で先程と同様に長時間運転安定性検証を行った結果を示します。
図3.1.2-1 は autovacuum が OFF の場合において、PostgreSQL 8.2 と 8.3 のスループットを示したグラフです。 今回の検証結果の場合、PostgreSQL 8.3 の方が性能は約 2 割向上し、なおかつ 48 時間一定の負荷をかけ続けても性能の低下は見られませんでした。
これは、FILLFACTOR と HOT がとても有効に作用したためです。 TPC-C はランダムで一意な ID をキーにして表を更新するトランザクションを主体としたベンチマークモデルです。 同一ページ内で複数行の同時更新が発生する可能性が低いため、HOT が特に有効に機能した結果となりました。
続いて 図3.1.2-2 を見てみましょう。これは autovacuum を ON にした場合の結果です。 autovacuum を ON にすると、8.3 では急激に性能が低下する時間帯が現れました。 これは、約 30GB の大きなテーブルに VACUUM が実行されたことにより、ストレージのディスク I/O リソースが消費され枯渇したために発生した事象です。 このように autovacuum に頼って運用していると、突然急激に性能が低下するアクシデントに見舞われる事があるため、それを防止する策を講じなければなりません。
最も有効な策として、VACUUM 遅延機能(VACUUM コスト遅延)があります。 (VACUUM 遅延機能は PostgreSQL のマニュアルを参照してください)
VACUUM 遅延機能を ON にして再度検証を行ったところ、このように急激な性能低下は抑えられ、 autovacuum + VACUUM 遅延機能の組み合わせは有効だという結果が出ました。 ただし、VACUUM が要求する単位時間当たりのディスク I/O が減るため、VACUUM に要する時間はどうしても長くなってしまいます。 今回の検証結果の場合は約 16 倍時間が長くなりました。
上記の検証結果から、PostgreSQL 8.3 をシステムへ適用する際には以下の 3 点を検討ポイントとしました。
- 検討ポイント1:大容量のテーブルへ VACUUM を実行する事による急激な性能低下を防ぐ事を検討する事
-
autovacuum + VACUUM 遅延機能を使いましょう!
ただし、VACUUM が業務アプリケーションやバッチ処理に与える影響(スループット低下やレスポンス遅延など)について問題がない事を 、検証により確認しておく必要があります。
- 検討ポイント2:テーブルの断片化対策を検討する事
-
これはPostgreSQL8.2と同じ検討を行います。
- 検討ポイント3:FILLFACTOR の領域を検討する事
-
HOT を有効に機能させるためには必須の領域です。ただし多く取りすぎると、テーブル(インデックス)サイズが増加するので、逆に性能が低下してしまいます。 1 ページに数レコード分の空き(FILLFACTOR の領域)が確保できる程度の値にします。
上記の検討ポイントをメインにシステムの適用判定を行ってきました。 PostgreSQL 8.3 ではスループットが向上し、性能が安定してきたことから、システム導入の検討対象となり、実導入も増え始めました。
3.1.3 処理性能と安定性 - ver. 8.4 -
PostgreSQL 8.4 で先程と同様に長時間運転安定性検証を行った結果を示します。
autovacuum + VACUUM 遅延機能の有効性を確認するため、この機能を ON または OFF にして検証を行いました。
どちらも時間経過と共に性能が低下しておらず、また、若干性能が細かく上下していますが、おおむね安定していると言えます。 また、OFF より ON の方が性能は少し低いように見えます。
これは VACUUM 遅延機能のパラメータにチューニングの余地がある事と、PostgreSQL 8.4 から default_statistics_target のデフォルト値が 10 から 100 に増加したため ANALYZE の処理負荷が増した事の 2 つが関係していると思われます。 更新が多いシステムで autovacuum を ON にしている場合、ANALYZE の処理負荷が性能に影響を与えている場合もあり得るという事を 頭の片隅に置いておくと、役に立つかもしれません。
話は若干逸れましたが、PostgreSQL 8.4 は PostgreSQL 8.3 と同様に、以下の理由から実システムへの適用性は、非常に高いと考えられます。
- HOT 機能が有効に働き、性能が安定。
- autovacuum + VACUUM 遅延機能を ON にしても性能が安定。