ぱいぱいにっき

Pythonが好きすぎるけれど、今からPerlを好きになりますにっき

kuiperbeltのベンチマーク

golang大好きです、マコピーです。

昨日書いたkuiperbeltですが少しいじりまして、リファクタしたりComet部分を別のファイルに追い出したりしていました。
大きいのはコマンドをekboっていう名前に変えたことでしょうか。その際のディレクトリ構造はpecoを参考にしています。
あと、切断検知を入れました。今まではコネクションをクライアントがわから切ってもUUIDが残っちゃうという致命的な問題があったのでそれを検知してUUIDを消すのをしています。

さて、グループ機能はないですけれどここらでベンチでも取ろうかなという気になったのでやってみます。
初めは手元のMacbookAirでやってたんですけれどkuperbelt側とベンチ側でリソース食い合っちゃってあんまりよろしくなかったのでvultr上のインスタンス2台でやってみました。

準備

拙作のgo-vultrで立てていきます。

kuiperbelt側

1 core, 768MB memory, 15GB SSDインスタンスubuntuで東京リージョンに立てます。

$ vultr create --osid 160 --dcid 25 --vpsplanid 31

ログイン後、aptでgoを導入してkuiperbeltをgo get

# apt-get update
# apt-get install golang
# export GOPATH=$HOME
# export PATH=$HOME/src:$PATH
# go get github.com/mackee/kuiperbelt
# go install github.com/mackee/kuperbelt/cmd/ekbo

あとは立ち上げてこちらは放置

# ekbo
2014/06/22 12:07:11 Kuiperbelt start listen and serve on 8080

負荷をかける側

クライアント接続用のcurlベンチマークツールwrkを導入します。
kuiperbelt側と同じスペックでwrkを実行するとメモリが足りなくて怒られるので2 core, 2GB memory, 40GB SSDインスタンスで立てます。

$ vultr create --osid 160 --dcid 25 --vpsplanid 8

ログイン後、aptでbuild-essentialやopensslを入れます(この辺り曖昧

# apt-get update
# apt-get install build-essential libssl-dev

wrkをcloneしてきてbuild

# git clone github.com/wg/wrk src/github.com/wg/wrk
# cd src/github.com/wg/wrk
# make
# mkdir ~/bin
# mv wrk ~/bin
# export PATH=$HOME/src:$PATH

あと、wrkはPOSTでリクエストするにはluaで設定を書かなければならないっぽいので以下のスクリプトをどっかにおいておく。この例では~/work/wrk.luaに保存

wrk.method = "POST"
wrk.body   = "{\"ping\":1}"
wrk.headers["Content-Type"] = "application/json"

ベンチマーク

負荷をかける側でクライアントをconnect
ここではkuiperbelt側のホスト名をkuiperbeltにします。実際のベンチはそれぞれのIPアドレスを直接指定して行いました。結果は/dev/nullに捨てるという感じで。

# curl --silent http://kuiperbelt:8080/connect > /dev/null

これとは別のシェルでwrkで負荷をかけます
この例では8スレッド400接続30秒間でかけます

# wrk -t8 -c400 -d30s -s work/wrk.lua http://kuiperbelt:8080/broadcast

複数コネクションを張る時は以下の様な感じにしたけれど、なんかもっといけているツールがあれば教えて欲しいです

# wrk -t1 -c2 -d1m --timeout 1m http://kuiperbelt:8080/connect

結果

各生データはこちら
https://gist.github.com/mackee/3d135cee3894afa05682

グラフにすると
f:id:mackee_w:20140622233129p:plain
縦軸がreq/sec、横軸が接続数です。

きれいな双曲線になっていてまあそうだよな〜という感じです。
ちなみに1000コネクション時はtimeoutが発生しているのでグラフには載せませんでした。この規模になってくるとマルチコア使うとか台数並べるとかそういう施策が必要そうです。

まとめ

たぶん普通に使う分には大丈夫だけれど大規模環境レベルになると厳しそう。
あと1対1の/sendを使う場合は128 connection時と1000 connection時で性能劣化が見られなかったのでまあそういうアーキテクチャということです。
それとキューに溜まりすぎて送りきれてない説があるのではあどないしようという感じです。