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
グラフにすると
縦軸がreq/sec、横軸が接続数です。
きれいな双曲線になっていてまあそうだよな〜という感じです。
ちなみに1000コネクション時はtimeoutが発生しているのでグラフには載せませんでした。この規模になってくるとマルチコア使うとか台数並べるとかそういう施策が必要そうです。
まとめ
たぶん普通に使う分には大丈夫だけれど大規模環境レベルになると厳しそう。
あと1対1の/sendを使う場合は128 connection時と1000 connection時で性能劣化が見られなかったのでまあそういうアーキテクチャということです。
それとキューに溜まりすぎて送りきれてない説があるのではあどないしようという感じです。