PostgreSQLストリーミングレプリケーション、いよいよ最終回となりました。
前回では各レプリケーション構成下でのベンチマークを測定しましたが、今回はPostgreSQLのパラメータチューニングによってどの程度パフォーマンスが上がるかを検証してみたいと思います。
postgresql.confの設定
まず、一般的な設定変更を行ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 |
# vi /usr/local/pgsql/data/postgresql.conf --------------------------------------------------------------------------------- max_connections = 300 # (change requires restart) shared_buffers = 600MB # min 128kB work_mem = 32MB # min 64kB maintenance_work_mem = 256MB # min 1MB wal_buffers = 16MB # min 32kB, -1 sets based on shared_buffers checkpoint_segments = 32 # in logfile segments, min 1, 16MB each checkpoint_timeout = 10min # range 30s-1h checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0 effective_cache_size = 1GB --------------------------------------------------------------------------------- |
チューニング前後比較
運用上、良く使われるであろうremote_writeでパフォーマンスを計測しました。
同時接続数 | before | after |
---|---|---|
10 | 311.438433 | 288.125800 |
20 | 305.639230 | 252.362676 |
30 | 249.080966 | 268.283054 |
40 | 321.211022 | 377.644046 |
50 | 318.080888 | 384.685279 |
60 | 375.444728 | 376.620584 |
70 | 381.336274 | 376.829394 |
80 | 362.426925 | 380.413093 |
90 | 357.318007 | 387.246141 |
100 | 338.282760 | 387.697821 |
約104.8%のパフォーマンスアップとなりました。
I/Oスケジューラ設定変更
上記の設定内容に加え、ディスク設定を変更してみました。
今回の構成ではディスク性能がボトルネックになっていそうなのですが、少しでもパフォーマンスが出るようにI/Oスケジューラを変更します。
CentOS標準のcfqではI/Oのリクエストを均一に処理しようとします。
これをPostgreSQLで推奨されるdeadlineに変更します。
deadlineでは処理待ちの時間がかかっているI/Oリクエストを優先して処理するI/Oスケジューラです。
1 2 3 4 5 |
# cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq] # echo deadline > /sys/block/sda/queue/scheduler # cat /sys/block/sda/queue/scheduler noop anticipatory [deadline] cfq |
ちなみにSSD等ではOSが関与しないnoopにした方が良いそうです。
I/Oスケジューラ変更結果
同時接続数 | cfq | deadline |
---|---|---|
10 | 288.125800 | 327.992339 |
20 | 252.362676 | 313.992751 |
30 | 268.283054 | 265.219558 |
40 | 377.644046 | 369.047703 |
50 | 384.685279 | 388.308045 |
60 | 376.620584 | 385.296396 |
70 | 376.829394 | 394.342246 |
80 | 380.413093 | 383.741045 |
90 | 387.246141 | 386.482870 |
100 | 387.697821 | 390.683908 |
多少ばらつきはありますがI/Oスケジューラをdeadlineに変更するだけで、平均約103.6%のパフォーマンスアップとなることがわかりました。
なお、上記のechoコマンドでdeadlineを設定した場合、再起動するとcfqに戻ってしまいますが、grub.confに記述することで再起動後もdeadlineを使うことができます。
1 2 3 4 5 6 7 8 9 10 11 12 |
# vi /etc/grub.conf ------------------------------------------------------------------------------------------------------------- default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS 6 (2.6.32-504.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=UUID=1b533e99-0226-40c2-8d5f-c6ef251ed619 rd_NO_LUKS rd_NO_MD crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=jp106 LANG=ja_JP.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet elevator=deadline # elevator=deadlineを追加 initrd /initramfs-2.6.32-504.el6.x86_64.img ------------------------------------------------------------------------------------------------------------- |
運用上の注意点
さて、チューニングによってもパフォーマンスが変わることがわかりましたが、このまま運用してしまうと問題が出てきました。
スレーブが参照中のデータをマスター側で削除してしまう現象が発生しスレーブの参照がキャンセルされてしまったのです。
これを防ぐために「hot_standby_feedback」パラメータを有効にします。
1 2 3 4 5 6 |
# vi /usr/local/pgsql/data/postgresql.conf ------------------------------------------------------------------------- hot_standby_feedback = on # send info from standby to prevent # query conflicts ------------------------------------------------------------------------- # /etc/rc.d/init.d/postgres restart |
まとめ
I/Oスケジューラ変更はしておいた方が良い
PostgreSQLのチューニングというと、どうしてもpostgresql.confを弄り倒すイメージがありますが、I/Oスケジューラの変更はお手軽なので是非ともやっておきたいチューニングだと思います。
場合によってはマスターとスレーブでパラメータを変更すべき
今回はマスターとスレーブで同じ設定を行いましたが実運用では性能の良いマスターと、そこそこの性能のスレーブを何台か投入するという場面も出てくるので、マスターとスレーブで違う設定を行うということも有用だと感じました。
最後に
合計4回で構成したPostgreSQLストリーミングレプリケーションいかがでしたでしょうか。
うまく活用することで、スレーブに投入した台数分のパフォーマンスアップが期待できるためPostgreSQLの負荷が多い場合には非常に有効な方法と言えると思います。
ちなみに実際にデータベースの負荷が問題になっていたサーバでは、ストリーミングレプリケーションにより参照クエリを分散することで、想像以上のパフォーマンスを発揮することができました。
今後もさまざまな機能強化が行われていくPostgreSQLを注視していきたいと思います。