DBT-1によるパッチを適用したPostgreSQL8.1.2の32ビットマシン(IA32)でのCPUスケーラビリティに関する考察(チューニング有り)

PostgreSQL8.1は,システムがCPU数8以下環境におけるDBT-1のワークロードにおいては,BT値はほぼ理論値どおりに推移したが,エンタプライズ環境で必要になると思われるCPU数8を超える環境では,CPU数に応じたスケーラビリティを示すことができないことがわかった。そこでそのボトルネックの原因を調査し,ボトルネックを解消するパッチを作成した。
本評価では,パッチを適用したPostgreSQL8.1に対してパラメタのチューニングを実施した後,CPU数を段階的に増加させてスケーラビリティの評価を行った。
最大のスループットを計測した仮想ユーザ数のは,CPU数2から16までほぼ理論値通りに推移し,ボトルネックの解消が実証できた。
CPU数16においては,eu8000においてもスループットの頭打ちはみられていないため,euを増加させることによってスループットの向上が期待できる。

ユニアデックス株式会社
ミラクルリナックス
SRA OSS, Inc

本評価ではチューニングを実施した後,CPU数を段階的に増加させてパッチを適用したPostgreSQLのCPUに対してスケーラビリティの評価を行った。
本測定では,PostgreSQLに対して基本的なチューニングをした上で,同一マシンの上でCPUの数を2,4,8,12,16と変化させてDBT-1を実行し,PostgreSQLのCPU数に対する性能推移を測定した。なおメモリはすべて16GBに固定している。

PostgreSQLのパラメタ・チューニング

PostgreSQLの一般的なチューニング項目を洗い出し,必要に応じてパラメタの効果を検証しつつ主要な項目やDBT-1のワークロードモデルに適した設定値を決定し,明示的に指定した(表1)。パラメタの詳細については,PostgreSQLのマニュアルを参照してほしい。

表1 postgresql.confチューニング項目
設定項目 設定値 デフォルト
shared_buffers1 10000 1000
wal_buffers 32 8
checkpoint_segments 16 3
random_page_count 3 4
stats_start_collector on on

注)stats_start_collectorは,統計情報採取のために必要である。

測定結果

同じチューニング・パラメタを使用して,CPUの数を変えて, DBT-1を実施して性能推移を測定した(図1)。

図1 CPU数とその性能推移

パッチなしの場合は,CPU数8仮想ユーザ数5600以上でBT値が頭打ちになっていたが,パッチを適用した場合,CPU数2,CPU数4,CPU数8,CPU数12,CPU数16のそれぞれの測定においてスループットの最大値が,CPUの数に比例し向上していることが確認できる。CPU数16においては,仮想ユーザ数8000までBT値は頭打にならず,さらなるBT値の伸びを期待できる。よって, CPU数が2から16まで,仮想ユーザ数5600までにおいて理論値どおりにスケールアップしていると言える。CPU数8以上においてBT値が理論値に沿って増加しており、12以上のボトルネックを解消させることができている。

パッチなしの測定結果のページ

パッチなしの場合のPostgreSQL8.1性能評価結果


次にパッチなしの場合にBT値が頭打ちになった仮想ユーザ数5600に着目して各CPU数における平均リソース利用率を見ることにする(図2)。

図2 CPU数と平均リソース使用率


図2のグラフから以下の傾向を読み取ることができる。

  • systemのリソース使用率は,CPU数の増加とともに減少している。
  • iowaitは,どのCPU数でも1%以下であり,ディスクアクセスのボトルネックは発生していない。
  • CPU数の増加とともにidleが増え,user部分の使用率が減少している。よって,CPU数が多いほど能力を使いきれていない。この傾向は,パッチがなかったときと同様である。

最大のスループットを計測した仮想ユーザ数は,CPU数2の仮想ユーザ数3200においてBT値=約260,CPU数4の仮想ユーザ数4000においてBT値=約440,CPU数8の仮想ユーザ数5600でBT値=約640BT/秒,CPU数12でBT値=約810,CPU数16でユーザ数8000でBT値=約985となった。仮想ユーザ数8000まで,ほぼ理論値どおりに推移している。
パッチ適用前と後でのリソースの利用状況の詳細をoprofileを使用してプロファイリングする。表2と表3は,そのプロファイリングした結果の抜粋である

表2 パッチ適用前CPU数12のプロファイリングの抜粋
順位 出現回数 % アプリケーション名 シンボル名
1 14451248 18.1305 postgres s_lock
2 48102671 6.0349 postgres LWLockAcquire
3 32748844 4.1086 postgres LWLockRelease
4 24633989 3.0905 postgres HeapTupleSatisfiesSnapshot
5 23499726 2.9482 postgres wchareq
6 23092918 2.8972 postgres pg_mblen
7 19075965 2.3932 postgres MBMatchText
8 18342137 2.3012 postgres AllocSetAlloc
9 18305841 2.2966 postgres memcpy
10 18151762 2.2773 postgres PinBuffer

表3 パッチ適用後CPU数12のプロファイリングの抜粋
順位 出現回数 % アプリケーション名 シンボル名
1 69597515 8.9897 vmlinux get_offset_pmtmr
2 36941434 4.7716 postgres LWLockAcquire
3 32926091 4.2529 postgres HeapTupleSatisfiesSnapshot
4 27811729 3.5923 postgres wchareq
5 26964252 3.4829 postgres pg_mblen
6 23668219 3.0571 postgres MBMatchText
7 21326245 2.7546 postgres PinBuffer
8 20664003 2.6691 libc-2.3.4.so memcpy
9 18736586 2.4201 oprofiled odb_insert
10 18421315 2.3794 postgres pg_euc_mblen

当該パッチは、BufferMappingLockの粒度をより小さくしてロックコンフリクトを減少させるという戦略のもと作成されている。当該パッチにより8CPU以上 で観測されたロックコンフリクトによる性能低下(スケーラビリティボトルネック)が16CPUまで解消されている事を確認した。

oprofileのトップ10を分析すると(12CPU)、パッチ未適用ではs_lockが18.1%でトップだが、パッチ適用後はトップ10から姿を消しているので、ロックコンフリクトが解消されている事を確認できる。
トップ1のget_offset_pmtmrはタイマ割り込みのための処理である。callgraphを解析する必要はあるが、原因として以下のようなことが考えられる。

  • PostgreSQLではロックを獲得できないとsleepして待つが、定期的にタイマ割り込みで起床している。
  • デッドロック検出のために、定期的にタイマ割り込みが発生している。

また、トップ10のwchareq(4位)、pg_mblen(5)、MBMatchText(6)、pg_euc_mblen(10)はいずれもマルチバイト関連の関数で総計12.5%をそこで消費している。 これらは純粋にアルゴリズム的な変更で性能向上に寄与すると考えられるのでソースコード分析等によりさらに最大10%程度の性能向上が見込まれる。

結論としてパッチを適用することでPostgreSQL8.1のCPUスケーラビリティが向上していることがわかった。しかし,CPUスケーラビリティが向上したPostgreSQL8.1を 評価したことで,別な場所で純粋な待ちが発生していることがわかった。この待ちを解析することでPostgreSQL8.1の処理性能を更に向上させることができる可能性がある

なお、今回のBufferMappingLockに対するロックコンフリクトの問題は、コミュニティでも改良が進められていたようであり、PostgresSQL 8.2に今回作成したパッチと同様の考えで修正されたコードを含んでいることがわかった。 したがって、PostgreSQL 8.2でも今回の問題が解消され、12CPU以上でもスケールアップすることが期待できる。

このデータの性能データ

関連する考察データ

コメント表示 コメント登録