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の一般的なチューニング項目を洗い出し,必要に応じてパラメタの効果を検証しつつ主要な項目やDBT-1のワークロードモデルに適した設定値を決定し,明示的に指定した(表1)。パラメタの詳細については,PostgreSQLのマニュアルを参照してほしい。
| 設定項目 | 設定値 | デフォルト |
|---|---|---|
| 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以上のボトルネックを解消させることができている。
次にパッチなしの場合にBT値が頭打ちになった仮想ユーザ数5600に着目して各CPU数における平均リソース利用率を見ることにする(図2)。
図2 CPU数と平均リソース使用率
図2のグラフから以下の傾向を読み取ることができる。
最大のスループットを計測した仮想ユーザ数は,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は,そのプロファイリングした結果の抜粋である
| 順位 | 出現回数 | % | アプリケーション名 | シンボル名 |
|---|---|---|---|---|
| 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 |
| 順位 | 出現回数 | % | アプリケーション名 | シンボル名 |
|---|---|---|---|---|
| 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を解析する必要はあるが、原因として以下のようなことが考えられる。
また、トップ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以上でもスケールアップすることが期待できる。