MySQL5.7 / RDS / Aurora / Cloud SQL の性能比較

ウズウズしたので、今をときめくかもしれない3倍界王拳のMySQL5.7、僕らの輝かしい希望Aurora、良い感じに枯れてきたRDS、あとは一見捨てられかけてる子Cloud SQLも交えてベンチマークを採ってみました。

内容は、適当にベンチマークツールを走らせて数値出たドーン!速い遅~いとキャッハウフフするものではなく、要所を検証するためのものなので、そんなに楽しいものではないかもしれません。



目的

上から順に、このくらいやれば十分かなーと考えていきました。

GoogleのCloud SQLは使い物になるのか?

Cloud SQLをサラッと見ただけでも気になるところがいくつもあります。

  • CPUについて公表されていなく、監視項目にもない
  • メモリが最大でも16GBと心もとない
  • ディスク容量も最大で500GBと厳しい
  • IOPS上限は不明だし、料金コミコミ分も容易く足が出る設計
  • スペックの最終更新が3年前という停滞感

  • 初見の感想としては、GCPとしてはCloud SQLをとうに捨てていて、
    Datastoreを推奨しているのではないか。
    それとも実は、外見は不安とショボさがにじみ出ているけども、
    使ってみたら謎技術で高スループットが出たり、便利機能が盛り沢山なのでは。

    それらを払拭するために、まずは単体で十分かどうかを調べようと考えました。

    他の環境とも比較してみよう

    せっかくベンチマークの手順も確立したのなら、そこそこ経験のあるRDSでも採取して比較してみようかと。さらにAuroraも日本にきたし、やってしまえと。ついでに先日、旧Verより3倍速いという触れ込みでGAされたMySQL5.7もやってしまえと。いう感じで久々にウキウキウォッチンなベンチマークとなりました。

    あ、もちろん今回のRDSはMySQLですし、AuroraはRDSのエンジンの1つということは理解した上で、一般的にわかりやすいであろう表記にしているので、そういう突っ込みはいらんですたい。

    Availability Zone間の差も知っておこう

    WEB/APサーバーと同AZにあるか、別AZかで、どのくらいのパフォーマンス差があるかを知っておくことで、余計な誤解を回避し、適切な設計と運用ができるためです。

    Cloud SQLのスペック間の差はどのようになっているのか

    当初予定していた、それぞれの低めのスペックにおいて、Cloud SQLだけ満足できない数値が出たため、その上のスペックも全部計測してみました。

    ついでに、レプリケーションデータの同期/非同期の違いもみることにしました。

    スペック

    今回のインスタンス・スペックは以下の条件を元に選定しています。

  • テストデータ1GB以上のメモリがあること・・・2GB以上を目安
  • CPUは2vCPU以上(GCPは不明)
  • 時間単位の価格が近いこと

  • で、こんな感じのインスタンスになりました。

    RDSAuroraEC2 for 5.7CloudSQL
    Namem3.larger3.largem3.largeD4,D8,D16,D32
    $/hour$0.24/h$0.35/h$0.193$0.18/h~$1.46/h
    vCPU222?
    Mem(GB)7.5157.52,4,8,16
    IOPS3000自動3000不明
    CloudSQLの価格は実戦的という意味で、per Dayの価格を24hourで割った価格にしています。
    メモリは2GBあれば検証としては十分なので格差は関係ありません。
    IOPSはEBSならGeneral Purposeの1000GB*3で最大確保しています。
    その他、ネットワーク周りなどポイントがあれば都度、補足していきます。

    ベンチマークのデータ

    今回、採取した全データはこちらになります。一部、目的に対して不要と判断したら省略しています。まぁ、こんなオレオレメモデータを見ても楽しくないでしょうから、1つ1つ考察していきましょう。


    手法について

    私がよくやる計測方法なのですが、innodb_buffer_pool_size がデータ容量より大きい健全な状態と、最小の16MBで過負荷ストレージを演出し、それぞれで参照/更新を別々にランダムアクセスをすることで、最初のボトルネックを炙り出します。

    CPU/転送量/IOPSを中心に、ボトルネックとなる項目の天井を確認できるまでリクエストを突っ込む感じです。

    具体的には sysbench で 1GB のテストデータを作成し、ランダムクエリを実行し、bash や 管理画面グラフ でQPSやIOPSを取得しています。この辺のコマンドベースの説明については、気が向いたら別途書こうと思います。

    あと、RTT(Round-Trip delay Time)については、ICMPを受け付けていない環境があるので、全て nping で3306ポートに対して計測したものになります。

    精度について

    もちろん、同じ項目を何度か試行していますし、少々のバラつきがある結果もあるのですが、検証結果に大きな影響を与えない範囲で値をザックリ中間値で取ったり、適当に見やすく繰り上げています。あまりにバラつきが気になったポイントは補足していきます。

    注意を払った点

    特にクラウドにおいて、ボトルネックとして確信しづらいネットワーク・トラフィックですが、クライアントがボトルネックになっているとゴミ検証になってしまうので、そもそも高ネットワーク性能なインスタンスにしたり、それでも怪しければクライアント数を増やし、データベース・サーバー側がボトルネックとなるように気を使って調整しました。

    RDSについて考察


    オンメモリでは

    参照は正常にCPUボトルネックになりました。
    更新は得た情報だけでは明確なボトルネックを確認できず……
    とはいえ、このRDSにおける参照15000qps, 更新4800qps|1500IOPS を基準に他と比較していってよさ気な程度の数値は出た感じです。

    メモリ不足では

    参照はReadIOPSを3600出しているので、ここがボトルネックのようです。General Purposeの説明では3IOPS/GBで3000上限に加えて、もう少しだけ性能が出るよ、と書いてあったので、そのチョイブースト部分がノッたようです。IOPSのわりにQPSが10000出ていい感じなので、ディスクの低レイテンシが伺えます。

    更新はReadIOPSが1600、WriteIOPSが2500、合計で4000超えしてボトルネックとなっています。QPSは1000とオンメモリに比べてだいぶ落ちますが、まぁこんなもんというか十分でしょう。

    念のため、Provisioned IOPS = 10000 でも試したのですが、ほとんど変わらず。参照はサーバー・ネットワークのModerate品質が引っかかって450Mbpsあたりで天井打ってたように見えたので納得できましたが、更新はSHOW STATUSを細かく見ないとわからない何かがあったかもしれません。

    AZ間の差は

    同クライアント条件において、QPSは約半減しました。同AZが 0.25ms に対して、別AZが 2.15ms と大きいので順当です。とはいっても、どちらも十分に小さいRTTですし、なにより安定したRTTだったのが好感触でした。

    Auroraについて考察


    オンメモリでは

    参照は正常にCPUボトルネックになり、なんとRDSの倍以上の36000QPSを観測。これが、あの自信満々ぽいQueryCache周りの改善の成果でしょうか。その代わりか、更新QPSはRDSの半分以下の1800、かつCPU利用率も高めと不安要素も見えました。

    ただ、明確なボトルネックは見えていないため、テストデータが1GBであるためにIOPSがここ止まりな可能性が高く、むしろ自動拡張ストレージに1GBだけで、よくこんなに出させてくれたという感じです。大容量になった時の性能上限には期待したいところ。

    それとCPUについては、CPU利用率が高く見える、という事前情報がありますので、RDSとの比較は難しいところです。高く見えるのは我慢するとしても、じゃあどの程度をスケールアップのラインとして認識すべきか、という点が運用における重要課題となります。今のところは感覚で掴むしかないのでしょうか……

    メモリ不足では

    参照はRDSとほぼ同じQPSが出て、ReadIOPSが半減という内容。仕組みが完全にMySQLと異なるので、ファイルシステムやInnoDBのブロックサイズが違うかもしれないし、読み書きの手法がそもそも全く異なってそうなので、気にしてもしょうがないです。気になる人は、Auroraの詳しい公開資料を漁れば、悟りを開けると思います。

    更新はQPSこそ低めなものの、Read/Write IOPSが1200ずつ出ているので、これまでの単発Reads,単発Writesの最大1800と見比べると、合計2400は傾向的に上限値であると納得いくところ。

    少なくともAuroraでデータ容量が膨らんでメモリ不足になっても、異常な劣化や性能維持はなく、これまでのMySQLと近い感覚で対処していけばよさそうです。

    AZ間の差は

    RDSと同じ程度のRTTとQPSの低下なので、ネットワーク的には同じのようです。

    SHOW STATUSの値

    MySQLの読み書き処理は色々あるので、IOPSの値は監視機能のグラフから採りましたが、実行直後には SHOW STATUS の Innodb_data_reads や Innodb_data_writes を使って推測IOPS値を表示したりしていました。

    なんとAuroraではこれらの値が全くカウントされないことがわかり、これまでのMySQLにおけるSHOW STATUSフィーリングは通用しないのでは疑惑が上がりました。ガチンコで使用する前には variables と status は一通り値をチェックして、感覚を磨く必要がありそうです。

    MySQL5.7 on EC2について考察


    オンメモリでは

    3倍界王拳の噂は予想通り、RDSのv5.6とほぼ同じQPS(RTT差の分が低下?)でした。ウェーイ。

    触れ込みでは1024コネクションで3倍ということなので、1クエリあたりの速度が3倍でもなく、CPUリソースが1/3でもなく、並列で処理できる上限QPSが3倍であると推測できます。とはいえ、これまで例えば50万QPS付近で喘いでいた人にとっては、100万をゆうに越せる希望が見えることなので凄いことではあります。

    更新はきっちりCPUリソースを使いきっての8400QPSということで、RDSの倍近くであり、ボトルネックがハッキリしない現象も解消されています。このあたりが、5.6ではハードウェアリソース外のところで詰まっていたけども、キッチリ捌けるようになった改善が感じられるところでしょうか。

    CPUリソースに対するQPSは5.6と同程度でも、全体のレイテンシが減るならば、ユーザーの体感を気持ち程度でも向上させることができるかもしれません。

    メモリ不足では

    RDSに比べると参照・更新ともにQPSが劣っており、かつIOPSがボトルネックになったわけでもありません。IOPSを多く発生させる場合の、秘伝のタレ(my.cnf)に改良が必要な可能性が高いと思われます。

    AZ間の差は

    RDSとRTTが同じなので計測していません。

    Cloud SQLについて考察


    レプリケーションデータの同期と非同期

    CloudSQLでは設定で、AZ間のレプリケーションデータの同期と非同期を選択できます。同期にすると当然、更新QPSが低くなるので、両方を計測したところ、それらしい違いが認められました。

    同期ならば更新は600QPS程度まで、非同期ならば1000~3000QPSあたり。更新QPSが絶妙に微妙なところなので、1000以上の更新QPSを予定している場合は同期という選択を取れないか、DB分割という方針になりそうです。

    オンメモリでは

    CPU情報がないのでボトルネックを断言できませんが、スケールアップしてもあまり参照QPSが増えず、最大のD32でRDSの2vCPUと同じ程度とは物足りない印象です。かと思えば、別AZにするとQPSが増えたりして、何回かやってもイマイチ納得する安定した数値になりませんでした。

    とはいえ、少なくともスペック名の数値に比例したCPU性能ではなさそうな可能性が高いです。

    また、詰まった理由がCPUではない場合、ネットワークトラフィックの可能性が非常に高いです。少々信じがたいのですが、クライアント1台あたりのInOut bps合計値が 25Mbps 程度で天井を打ったので(PreemptibleVMだから、はないと思いますが)、Cloud SQLサーバー側もあまりトラフィックに強くないのかもしれません。この辺は上限解放などの仕組みがないか調べる必要があります。

    メモリ不足では

    innodb_buffer_pool_size を任意の値にできなかったので計測しませんでした。一応、テストデータ容量を増やせばメモリ不足は演出できますが、インメモリの結果がそんなに良いとはいえなかったので、あえて劣化版も計測する必要はないと判断しました。

    AZ間の差は

    RTTの平均値としては、同AZで 0.70ms、別AZで 0.85ms とあまり変わりない速度となっています。CloudSQLにIPv4を付与するとグローバルIPアドレスになるので、よりフラットなネットワーク設計になっているのでしょう。

    ただ、どちらの場合も、RTTのMinが0.50~Maxが8.0msなどと頻繁にバラつきが起きたのが気になりました。AZ間の差が小さいのはメリットですが、AWSの安定感と同AZの速さはより魅力的といえるでしょう。

    QPSに対してIOPSが低い件

    これだけちゃんと追求するのを忘れてました。そもそもグラフが合ってんのか疑惑が強いですが、現時点ではなんとも言いがたいので、やらないかもしれない宿題で。

    RDSの忘れ物

    ここまでツラツラ書いておいてなんですが、RDSの環境は非MultiAZだったので、MultiAZにすると同期処理によって更新QPSが遅くなる可能性が高いです(やってしまった…)。

    なのでRDSのデータと比較できるのは、EC2のMySQL5.7と、Cloud SQLの非同期の2つ、そして参照全般ということになります。Auroraは4/6のHDD書き込み完了条件があるので、RDSをMultiAZにしたら同じくらいになるかもしれないですね…

    これによって、クラウドでの多種ベンチマークをもうやりたくない負け犬オーラがまとわりつきました。以後、頑張ります。

    Google Cloud Platformの感想

    コンテナなだけあって、噂通りサーバーの起動は速いです。
    また、Cloud SQLのスペック変更やAZの切り替えもかなり速い印象でした。
    (さすがにMySQLとしては一時的に利用不可能になりますけど)

    ただ、やはりCloud SQLはリソース上限の低さや不可視が、ここ数年のデータベース事情的に厳しく、RDBMSを中心に据えるシステムの場合の多くはCompute Engine上にMySQLを自前で立てたり、Datastoreで開発するなどの路線変更を検討することになりそうです。

    BigQueryなど素晴らしいシステムがあるだけに、RDBMSをもう少しなんとかしてくれないかな、それとも脱RDBMS的な思考のプラットフォームなのかな、といった初見の印象は変わらずでした。

    MySQL5.7の課題メモ

    5.7で他と同様のベンチマークを流し終わった後、何も実行していないのにiowaitが20~40%出るほどのディスクの読み書きが永久に続く現象に遭遇しました。昔のミドルウェアだと、こういう現象はそれほど珍しくなかったですが、現代で久々に見たので、本番投入する前には原因追求と解消をしなくてはいけないかもしれません。

    おわりに

    この中から何を選べばいいのかは、適材適所だホイの逃げの一手を打ちたいところですが、あえて選ぶならば、もうAuroraでえぇんちゃうん、という印象です。次に、RDSが5.7対応したころには、それもえぇんちゃうんという感じかと。

    あとはGCPでのデータベースは皆どうしてんねん、という強い疑問が残ったくらいでしょうか。

    なんか、たいした比較結果にならなくて、スイマセン。

    何を選ぶにせよ、適切なクエリチューニングと、バックアップ・リストアの確立と、垂直・水平分割の手段を用意しておけば、そうそうクリティカルな事故には遭いませんよ、と適当に結べる程度には良い時代になってきたのではないでしょうか。チャンチャン。