コメント:

結論:heroku で C10K は 6dyno あればいける!

HerokuのC10K挑戦の記事を興味惹かれたheroku歴まだ3日(原因:食わず嫌い)のプログラマです^^

気になったことを自前で調査した結果をご報告します。

この記事における失敗の原因が、リクエストコネクション(heroku router がらみ)にあるのか
バックエンド(Redis やサーバプログラム)にあるのかを切り分けてみました。

調査目的は「確率的に100%コネクションを張るための Web dyno 数」の計算となります。

用意したサーバプログラムは nodejs(express) で構築した最小構成のウェブサーバ。

単純なリクエスト(25秒後に1バイトのtext/plainを送るだけ)に対して
Apache Bench の -n 10000 -c 10000 でリクエストを送信した結果で判断しています。

結論から書くと、1X dyno 6台で 10000リクエストが36~38秒で Fail 無しで完了できました。
少なくとも 13秒~25秒 の間は同時にコネクションがサーバプロセスに届いていることになります。

先んじて調査した 1X dyno 1台でのテストでは
  -c 1700 で 1~4 程度の 503 レスポンス
  -c 2000 で 96~140 程度の 503 レスポンス
という結果となりました。

(かなり適当な)確率的にはdyno1台あたり 1666 コネクションくらいはまず間違いな
く同時コネクションが張れるようです。


もしこのレスに反応頂けるようであれば、同じく100部屋×100ユーザ×100発言についても
検証してみたいと思います。乞うご期待!

小西です。
大変興味深いです。
えーと、これはWebSocketのテストではなくて、単純にhttpでの同時接続数のみを対象としたテストですよね?

私の行ったテストはPlay(Scala)ですが、Node.jsの方がフットプリントが小さく、また非同期IOでもあるので同時リクエストを大量に捌けるだろうと思います。
また、時期的にHeroku側でのRouter改修の真っ最中だった気がするので今はもう少し同時接続数あがっているかもしれません。
実際、HerokuのRouterの制限がなくEC2直接使用ならNodeはもっと多くの同時接続をさばけるはずです。(このテスト内容なら1台でも10000接続捌けるんじゃないかと思う。)

現在別のことをやっていてあまり時間が取れていませんが、近日NodeでのWebSocketテストも試したいと思っているので、ご興味あればWatchしてください。(^^;

あと5/22のHeroku MeetupでのLTと6/9のSalesforceのイベントでWebSocketの話をするのでそちらも是非(^^;

小西様、お返事ありがとうございます。

ご指摘の通り、C10K 問題に対するシステム寄りの仕様(Web Dynoが何台必要か?)を
確認したかったという動機が最初にありきですから、WebSocket とは結果が違うかも
しれません……が、 router(reverse proxy)の仕組み上同じ結果になるのではと推測しています。

お返事もらえたので予告通り 1X Web Dyno 6台と RedisCloud(無料の最大10コネクション) で、
100部屋100人100発言100%メッセージ到達を目指してみたいと思います。(7台かもしれませんけどw)

WebSocket については個人的に興味はありますが、(実は当方はComet以前からとある方法で
リアルタイム通信やってました。とある手法で特許も出願しましたが国際特許の申請と
審査請求までお金持たず諦めて失効した経緯がw)普及やブームになるには中々難しそうです。

チャット以外のアイデアもいくつか当てがありますので、イベントやご機会があれば是非(^^;/

そうですね。テスト方法はそれで良いと思います。
ただWebSocketを有効にするとHeroku側でRouterが切り替わるので「heroku labs:enable websockets」とした後だと結果が変わるかもしれません。

Cometとはまた懐かしいですね。(^^;
僕は元々Lingrを作ってた会社にいたんですよ。あんまり関わってませんでしたが。

WebSocketアプリはhttpアプリ開発の文法で作ろうとしてもあまり美味しくないと思います。
今はクラサバをずっとやってきた人が初めてWebをやろうとして壁にぶちあたったような状況に似ています。
ここでも根本的なパラダイムシフトが必要だと思っているんですが、そのためには何かしらのフレームワークが必要です。
が、今は何もないから自分で作ろうかなと思ってます。(^^;;;
(githubのroomframeworkという奴です。)

サーバーサイドはとりあえずPlayで作ってますがNode版も作りたいので、もし、NodeでWebSocket、Redisなどを使うテストコードを書くならソース公開していただけるととても助かります。(^^;

Cometが話題になってすぐLingrがリリースされて有名でしたね。
デザインも Web2.0 っぽくて、インターフェースもこなれてて
私もその時期かなりの時間日本語部屋に常駐してましたw

HerokuのWebSocketsプラグインの前後で挙動確認しましたが、
有効にしないと WebSocket 接続がルータ時点で拒否されてしまうようですね。
有効にすると、無事 WebSocket 通信がやり取りできるようになりました。

ただ、RedisのSub/Pub機能を使うには1Dynoあたり2本必要だったので
WebSocketのC10K挑戦は5Dynoでのチューニング勝負となりそうです。

普通のHTTP通信については、WebSocket有効後でも1666本同時接続ははミス無し、
1700でミス3件というほぼ同じ結果だったので、
単純に WebSocket(Upgadeヘッダかな?) リクエストの処理が違うだけなのかな?


WebSocket を含めたリアルタイムウェブ基盤技術の普及やブームについての
難しさやあれこれは、当方も思うところありましてw そちらもまたどこかで。

C10Kテスト中間報告なのですが、WebSockets有効時の 1X Dyno 1台 でのHTTPリクエストが、
3000コネクションでもH11多発(2634接続成功で366リクエストがH11)したり、
運がいいと同時接続4986コネクション(H11は14本のみ)行けたり謎な状態が続いております……。
(サーバ側での同時接続数のカウンタとベンチマーククライアントでの通信結果ログでの集計で一致を確認)
本格的に個別コネクションのログ記録をとって状況の集計をしないと挙動のブレの原因の推測すらできなさそうです。(ちなみに1X Dyno 5台にしても、3000接続でもH11発生していたりと解析は一筋縄ではいかない気配が出てきました……)
検証データ増えてきたので検証用リソースやログデータ公表のために初GitHub挑戦するか、
どこかにHeroku攻略ブログでも立ち上げた方がよさそうな気がしてきましたw

ん~、リクエスト数に応じてRouterの数が動的に変わっているのかもしれないです。この辺僕も結果が不安定だなぁと思いつつも放置したままなので。。。
Herokuで既にgitは使っているんだから、GitHub使うのには何のハードルもないですよ。(^^;
是非使いましょう。