前回までの設定でレプリケーションができるようになりました。
それでは実際にレプリケーション別にベンチマークを実行して比較してみたいと思います。
pg_benchの準備
まずベンチマークツールを準備します。PostgreSQLのベンチマークで有名なpg_benchの準備を行います。
1 2 3 4 |
# su - postgres $ cd /usr/local/src/postgresql-9.3.5/contrib/pgbench/ $ make $ make install |
次にベンチマーク用のデータベースを作成し初期化します。今回はベンチマーク用に「bench_db」というデータベース作成し使用することにしました。
1 2 |
$ created bench_db $ pgbench -i bench_db |
ベンチマークの実施方法
ベンチマークの実施には以下のコマンドを使用しました。
1 |
$ pgbench -c 10 -t 1000 -N bench_db |
同時接続数10で1接続あたり1000回の更新や参照のトランザクションを行うという内容です。
実際にコマンドを実行すると以下のような結果が得られます。
1 2 3 4 5 6 7 8 9 10 11 |
$ pgbench -c 10 -t 1000 -N bench_db starting vacuum...end. transaction type: Update only pgbench_accounts scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 tps = 322.875608 (including connections establishing) tps = 323.030168 (excluding connections establishing) |
10行目、11行目のtpsとして表示されているのが、1秒間あたりに実行できたトランザクション数となります。数値が大きいほど多くのトランザクションを実行できたことになります。
前者の「including connections establishing」は接続時間を含む結果であり、後者の「excluding connections establishing」は接続時間を含まない結果となっています。
今回は後者の「excluding connections establishing」の値をベンチマーク結果として使用することにしました。
ベンチマーク実行結果
同時接続数を10からmax_connections初期値の100まで上げていき、各レプリケーション構成によってどの程度パフォーマンスの違いが出るのかを計測し結果を次の表にまとめましたのでご覧ください。
synchronous_commit | |||||
---|---|---|---|---|---|
on | remote_write | local | off | ||
同 時 接 続 数 |
10 | 280.261470 | 311.438433 | 351.743383 | 6247.446356 |
20 | 254.200879 | 305.639230 | 350.453906 | 6561.537709 | |
30 | 258.331754 | 249.080966 | 282.679487 | 6590.480710 | |
40 | 250.372667 | 321.211022 | 320.671861 | 6621.393989 | |
50 | 275.564140 | 318.080888 | 350.964466 | 6570.056181 | |
60 | 310.976342 | 375.444728 | 435.216539 | 6602.207118 | |
70 | 282.817891 | 381.336274 | 458.184838 | 6588.127404 | |
80 | 294.541189 | 362.426925 | 453.522946 | 5708.684679 | |
90 | 293.994904 | 357.318007 | 440.773060 | 6328.789473 | |
100 | 279.233850 | 338.282760 | 443.758059 | 6604.836590 |
大変です。offだけ桁が違います。
正直、目を疑う結果となりましたが、localとoffの差はマスター側にディスク書き込みをするかしないかの違いなので、このサーバではディスクI/Oがボトルネックになっていると考えられそうです。 実際使用しているディスクはSATAのハードディスクでしたのでSSD等に載せ替えるのが良いかもしれません。
上記結果をグラフ化したのがこちら。offは桁違いなので省略いたしました。
スレーブ側の検索性能(参考)
次にスレーブ側の性能をpg_benchで計測してみました。
スレーブでは更新ができないため「-S」オプションにより参照だけのベンチマークを行います。
また、pg_benchを走らせる際にデータベースに対してvacuumが実行されるのですが、スレーブではvacuumもエラーになってしまうので「-n」オプションで回避しています。
1 |
$ pgbench -c 50 -S -n bench_db |
各レプリケーション構成の通常時とマスターベンチマーク時に、上記コマンドをスレーブにて実行して5回の平均を取得してみました。
通常時(マスターに負荷をかけていない状態)のスレーブの参照ベンチマーク結果
synchronous_commit | ||||
---|---|---|---|---|
on | remote_write | local | off | |
1回目 | 7019.711349 | 7111.768555 | 7057.561471 | 7903.014210 |
2回目 | 7044.535554 | 8565.603961 | 8463.530646 | 8257.638315 |
3回目 | 7443.799315 | 7816.652597 | 7058.358508 | 7174.012856 |
4回目 | 7475.294153 | 8078.196946 | 7374.740040 | 8268.289456 |
5回目 | 8080.285719 | 8723.567590 | 8621.284226 | 7314.432839 |
平均 | 7412.725218 | 8059.157930 | 7715.094978 | 7783.477535 |
マスターベンチマーク実行時のスレーブの参照ベンチマーク結果
synchronous_commit | ||||
---|---|---|---|---|
on | remote_write | local | off | |
1回目 | 8274.994621 | 8195.646473 | 8521.952550 | 7877.737514 |
2回目 | 7896.523950 | 7063.643427 | 7814.087236 | 7732.397198 |
3回目 | 7670.123336 | 8536.939337 | 8309.927039 | 7727.019843 |
4回目 | 8038.972941 | 8493.578854 | 8488.820224 | 7447.901926 |
5回目 | 8202.907110 | 7849.416788 | 7588.404917 | 7835.762420 |
平均 | 8016.704392 | 8027.844976 | 8144.638393 | 7724.163780 |
実際にはマスターのベンチマーク実行時に手動でスレーブにコマンドを流しているため、検証方法に一貫性がなくあくまで参考値でしかありません。
ですがこの結果によってマスターの負荷の有無やレプリケーション構成の違いによって、スレーブの参照性能は大きく変化しないことが分かりました。
まとめ
意外にベンチマーク差が出る結果に
レプリケーション毎のベンチマークでは予想通り、ほぼ、on < remote_write < local という結果になりました。
あくまで今回の環境下での結果ですが、remote_writeはonの約1.2倍、localはonの約1.5倍、offに至っては桁違いという大きな違いが発生しましたので、レプリケーションを行う場合にはパフォーマンスを重視するのか、データの保全性を重視するのかをきちんと見極める必要がありそうです。
スレーブの参照をうまく使えれば負荷分散となり速度向上が期待できる
スレーブ側はマスター側の負荷に関わらずある一定の参照性能が発揮できることが分かりました。このためストリーミングレプリケーションでは、うまくスレーブ側に参照クエリを渡すことによって、マスター側の負荷を下げ、結果として速度を向上させることができるといえます。
次回予告
次回はPostgreSQLレプリケーション最終回、「第4回 チューニングでパフォーマンスは向上する?」をお送りいたします。
今回の検証はレプリケーション設定以外のパラメータは初期の状態ですので、次回ではこれをチューニングしてどの程度パフォーマンスが上がるのかを検証したいと思います。お楽しみに!