この質問を今までとても良く受けてきた。"負荷が高い時には、リードレプリカがしばしば遅延し始める。N個のスキーマを利用しているが、MySQL 5.6のパラレルレプリケーションを使うとどのくらい性能が改善するのだろうか?"ここでは潜在的な効果を、素早く大雑把に見積もる方法をご紹介する。
基本的な考え方
MySQL 5.6では、スキーマレベルで並列処理が行われる。従って理論上は、N個のスキーマがあり、N個の並列スレッドを利用すれば、レプリケーションは最大N倍高速化する。これは少なくとも2つのことを仮定している。
- レプリケーションのスループットは並列スレッドの数に対し線形にスケールする
- 書込みはスキーマ間で均等に分布している
もちろんいずれの仮定も現実的ではない。しかし、書込みの分布を知るのは容易であり、これによりパラレルレプリケーションによりどの程度の恩恵がえられるかを見積もる助けとなる。
書込みはバイナリログに保存されるが、スロークエリの方がはるかに扱いやすいので、一定の間、全てのクエリに対してスロークエリログの記録を有効化する。long_query_time=0
として、pt-query-digestを出力されるログファイルの解析に利用するのだ。
例
テストサーバーに3つのスキーマがあるとし、それなりのスロークエリログファイルをえる為にsysbenchの負荷をいくらかかける。 負荷がかけ終わったら次のコマンドを実施する。
pt-query-digest --filter '$event->{arg} !~ m/^select|^set|^commit|^show|^admin|^rollback|^begin/i' --group-by db --report-format profile slow_query.log > digest.out
得られた結果は次の通りである。
# Profile
# Rank Query ID Response time Calls R/Call V/M Item
# ==== ======== ============== ====== ====== ===== ====
# 1 0x 791.6195 52.1% 100028 0.0079 0.70 db3
# 2 0x 525.1231 34.5% 100022 0.0053 0.68 db1
# 3 0x 203.4649 13.4% 100000 0.0020 0.64 db2
スレッドが3並列で、各スキーマが書込み負荷の33%を処理している理想的な環境においては、3倍の性能改善が見込めた。
しかし、結果レポートにおいては3つのレプリケーションスレッドは、最善のケースで25%(13.4/52.1 = 0.25)の時間しか同時に処理していないことが分かる。 負荷の一部では2レプリケーションスレッドのみが同時に動作することもありうるが、明確にする為にこれは無視する。
これは、理論上の200%の性能改善(100% 3並列スレッド稼働)に対し、せいぜい50%の性能改善(25%の時間 3並列稼働)しかえられないことを見積もれることを示している。 そして現実には、受けられる恩恵はそれよりはるかに低くなるだろう。
結論
MySQL 5.6におけるパラレルレプリケーションは大きな前進であるが、書込み負荷が全てのスキーマで均等に分布していない場合はあまり期待しないことだ。 ご紹介したpt-query-digestにより、ご利用の環境の負荷が、MySQL 5.6のスレーブのマルチスレッド処理に適しているかどうかを大雑把に把握できる。
MySQL 5.7では、並列処理が異なる方法で実現されていることだけでなく、バイナリログのグループコミットの設定を調整することによって並列レプリケーションの効率を調整できるため、はるかに改善されていることを期待している。