2015年12月25日金曜日

MySQL Routerをlocalhostに置いたらどれくらいの遅延になるかを考えるメモと、MySQL Routerは本当につらくなかったのかのまとめ

この記事は MySQL Fabric&Routerつらくない Advent Calendar 2015 の25日目の記事です。

まずはどうやって遅延を計測しようか考えているメモをだだだと書きなぐる。後半にまとめっぽいものを。

計測環境。サーバーもクライアントもc4.xlarge。サーバーはyumリポジトリーで5.7.10を突っ込んで起動しただけ。


# rpm -i http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
# yum install -y mysql-community-server
# service mysqld start
# grep password /var/log/mysqld.log
# mysql -p
mysql> UNINSTALL PLUGIN validate_password;
mysql> CREATE USER yoku0825;

クライアントは接続してSELECT NOW()して切断するだけのもの。


$ cat -n test.cc
     1  #include <unistd.h>
     2  #include "mysql.h"
     3
     4  int main()
     5  {
     6    MYSQL mysql;
     7    int m;
     8
     9    mysql_init(&mysql);
    10
    11    for (m= 0; m <= 10000; m++)
    12    {
    13      mysql_real_connect(&mysql, "172.31.15.74", "yoku0825", "", NULL,
    14                         3306, NULL, 0);
    15      mysql_query(&mysql, "SELECT NOW()");
    16      MYSQL_RES *res= mysql_store_result(&mysql);
    17      mysql_close(&mysql);
    18    }
    19  }
$ gcc -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -g3 -O0 test.cc
$ time ./a.out

real    0m6.865s
user    0m0.248s
sys     0m0.552s

直接接続だと大体700usくらい。
c4.xlargeは4コアあるので4つ起動してみると


$ time (./a.out & ./a.out & ./a.out & ./a.out ; wait)


real    0m22.573s
user    0m0.508s
sys     1m10.168s

これくらい。ダメだ。ほとんどsysにもっていかれてる。まともに並列処理を書けるC力がほしい。
Routerはソースからコンパイル。サーバーホストだけを指定して単にプロキシーするだけの状態にする。


$ wget http://dev.mysql.com/get/Downloads/MySQL-Router/mysql-router-2.0.2.tar.gz
$ tar xf mysql-router-2.0.2.tar.gz
$ cd mysql-router-2.0.2
$ cmake .
$ make
$ sudo make install
$ sudo cp -ip /usr/local/share/doc/mysqlrouter/sample_mysqlrouter.ini /usr/local/etc/mysqlrouter/mysqlrouter.ini
$ sudo vim /usr/local/etc/mysqlrouter/mysqlrouter.ini
..
[routing:basic_failover]
# To be more transparent, use MySQL Server port 3306
bind_port = 7001
mode = read-write
destinations = 172.31.15.74
..

mysql_real_connectの向き先を127.0.0.1:7001に変えて、中央値は大体これくらい。


$ time ./a.out

real    0m8.816s
user    0m0.192s
sys     0m0.916s

$ time (./a.out & ./a.out & ./a.out & ./a.out ; wait)

real    0m9.761s
user    0m1.432s
sys     0m4.192s

コンテキストスイッチが減ってRouter経由の方が快適という結果に。top見てても遥かに良い感じ(mysqlrouterが100%張り付くので、a.outは20%くらいずつになる。これが結果として綺麗にキャップになっていい感じになるという。。)
もっとちゃんとしたクライアントだと、シングルスレッドのmysqlrouterが問題になってくると思う。取り敢えず、10秒で10000コネクション * 4プロセスだから4000connection/sならさばけてる(mysqlrouterの%usrが張り付くけど)

これを超えてくる場合、mysqlrouterのプロセスを複数起動して分散させることになるし、MySQL Routerはどうやら動的に設定を変えることはできないので、gracefulっぽくするためには



tcpdump + pt-query-digestでレイテンシーを見てみると、直接接続の場合はmysql_real_connectの中央値が467usにクエリーの中央値が152us。

# Query 1: 1.40k QPS, 0.70x concurrency, ID 0x5D51E5F01B88B79E at byte 42297981
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: 2015-12-24 10:33:50.782145 to 10:33:57.922968
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         33   10000
# Exec time     75      5s   431us     1ms   498us   568us    39us   467us
# Rows affecte   0       0       0       0       0       0       0       0
# Query size    43 292.97k      30      30      30      30       0      30
# Warning coun   0       0       0       0       0       0       0       0
# String:
# Databases
# Hosts        172.31.5.70
# Users        yoku0825
# Query_time distribution
#   1us
#  10us
# 100us  ################################################################
#   1ms  #
#  10ms
# 100ms
#    1s
#  10s+
administrator command: Connect\G

# Query 2: 1.40k QPS, 0.22x concurrency, ID 0xF450CBDB69FA3A64 at byte 42299217
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: 2015-12-24 10:33:50.782371 to 10:33:57.923132
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         33   10000
# Exec time     24      2s   142us   419us   159us   204us    16us   152us
# Rows affecte   0       0       0       0       0       0       0       0
# Query size    17 117.19k      12      12      12      12       0      12
# Warning coun   0       0       0       0       0       0       0       0
# String:
# Databases
# Hosts        172.31.5.70
# Users        yoku0825
# Query_time distribution
#   1us
#  10us
# 100us  ################################################################
#   1ms
#  10ms
# 100ms
#    1s
#  10s+
# EXPLAIN /*!50100 PARTITIONS*/
SELECT NOW()\G


Router経由だと固定でレイテンシーがあがるだけだと思ってたけど、Connectの方がぁゃιぃ。フツーのクエリーを計測するよりも(ルーティング判定のぶん)コストが高そう。もうちょっと別のクエリーも投げるパターンにして計測しないとダメだ。

単純クエリーで10usくらいの差なら、まともなクエリーになるに従って十分問題ないと見ていいはず。あ、でも、往復のパケット量が増えればそれぞれのパケットにレイテンシーが載るから結果セットが転送されきるまでのレイテンシーは無視できないのかも知れない。これも計測パターン増やさないと。


# Query 1: 1.07k QPS, 0.62x concurrency, ID 0x5D51E5F01B88B79E at byte 5655092
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: 2015-12-24 10:35:26.307560 to 10:35:35.641810
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         33   10000
# Exec time     76      6s   488us     1ms   581us   690us    65us   541us
# Rows affecte   0       0       0       0       0       0       0       0
# Query size    43 292.97k      30      30      30      30       0      30
# Warning coun   0       0       0       0       0       0       0       0
# String:
# Databases
# Hosts        172.31.5.70
# Users        yoku0825
# Query_time distribution
#   1us
#  10us
# 100us  ################################################################
#   1ms  #
#  10ms
# 100ms
#    1s
#  10s+
administrator command: Connect\G

# Query 2: 1.07k QPS, 0.19x concurrency, ID 0xF450CBDB69FA3A64 at byte 45635077
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: 2015-12-24 10:35:26.307968 to 10:35:35.642044
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         33   10000
# Exec time     23      2s   145us   577us   174us   214us    28us   159us
# Rows affecte   0       0       0       0       0       0       0       0
# Query size    17 117.19k      12      12      12      12       0      12
# Warning coun   0       0       0       0       0       0       0       0
# String:
# Databases
# Hosts        172.31.5.70
# Users        yoku0825
# Query_time distribution
#   1us
#  10us
# 100us  ################################################################
#   1ms
#  10ms
# 100ms
#    1s
#  10s+
# EXPLAIN /*!50100 PARTITIONS*/
SELECT NOW()\G

MySQL Fabricが載ってくると当然結果は変わるだろうから、次はFabric Cache Pluginバージョンも試す(台数がかさむなぁ。。)

ダラダラ書いたけど、次に測らないといけないところはわかった気がする。


さて、本題(?)

MySQL Routerは本当につらくなかったのか?

残念ながら つらくなかったです。


# 情報量(主にドキュメント)

* 初期のMySQL Fabricはひどかった。
* それよりは、今のMySQL Routerはマシ。
* ただし、今のMySQL Fabricの方がMySQL Routerより情報ある(と思う)
* つまり、結局は今後に期待。
  * ただ、MySQL FabricよりはMySQL Routerの方が流行ると思うので、日本語の情報も充実していくんじゃないかなぁ。

# 安定性

* MySQL Fabricも良くなってるんじゃないか疑惑
  * 去年試してた時 は結構さっくり刺さってハングしてたけど、今年は1回も突き刺さってない
* MySQL Routerは取り敢えず安定。Fabric Cache Plugin使ってる時の動作が若干不安…?
  * 再現しないので、要追試。

# 使いやすさ、使いたさ

## MySQL Fabric

* グラフィカルなCLIでレプリケーションクラスターの管理。したい。
* GTID依存なので、まずGTIDをONにして回るのが大変。
  * バックアップからリストアしたやつをレプリケーションクラスターに追加とかもGTID依存なので、5.6だと苦労しそう(5.7ならきっといける)
  * GTID依存だからこそ色々簡単なんだよなー、と思うとGTIDはやっぱりいいものだったのだな。
  * MariaDBさんがいるとダメ(GTIDの実装が全然違って互換性がない)
* いろんな実装がコネクター依存すぎてブラックボックスが超怖い。Connector/Jでは上手くいくけど他はダメとかフツーにありそう。

## MySQL Router

* 次世代MySQL Proxyとして使い始められる
  * スレーブの分散、Routerに置き換えようかと真面目に検討中。
  * Lua書かなくていい。ただし、MySQL RouterのプラグインはC++な上にドキュメントがまだないぽい。
* Fabric Cache PluginはMySQL Fabricのブラックボックスを解消するものなので、とてもイケていると思う。
  * ただ、アレだけで1章書いてもいいんじゃないかってくらいもっと説明して欲しいところがいっぱいある。。
* MySQL Fabricと連携させないなら、4.0 5.5とかでもイケるんじゃないかな(old_passwordの壁があるか…?)

# デバッグとソースコードリーディング

* MySQL FabricはPythonで、俺のPython力の欠如によりつらかった
  * ゆるぼ: Pythonista
* MySQL RouterはC++でgdbで突き刺すスタイルなのでデバッグが楽
* とはいえこれはMySQLオタク向けの項目なので、ほとんどの人には無縁

というわけで!

つらくないよ!

つらくないから、僕と結託して 地雷 MySQL Router友達になってよ!

お待ちしております :)

0 件のコメント :

コメントを投稿