QA@IT
«回答へ戻る

回答を投稿

http://lingr.com/ というチャットサービスを作っている者です。

基本的に、あまりアクティビティの多くない(CPUをあまり使わない)コネクションを大量に扱う目的には、原理的にnode.jsはぴったりだと思います。

実際、Lingrでは、通常のweb部分にはRailsを使い、チャット用のプッシュを行うバックチャンネルをEventMachineというnode.jsと同じリアクターモデルで動作するRuby用のサーバで書いています(正確にいうとthin + async_sinatraです)。ブラウザの互換性を重視して現在もWebSocketsではなくComet/Long-pollで動作していますが、原理的な性能特性はどちらも同じです。

EventMachineもnode.jsも、ちゃんとFDの設定をすれば単体で10,000以上の同時接続をさばけるので、長期的に見てユーザ数が100万でデイリーアクティブ率が10%で平均滞在時間が144分だとして、保守的にみてもプロセス1個で足りるので、ほとんどの内部状態をグローバル変数で持たせることができ(シングルスレッド動作なのでハッシュのmutate atomicityなどを心配する必要もない)、非常に見通しの良いコードを書くことができます。

ただし、ある程度の規模になってくると、問題はバックエンド側になってきます。とくに「サーバーにログを残す」とあるので、おそらく間違いなくボトルネックはDBになってきます。いくら非同期で書けるといっても、DBへのコネクションは有限ですから、どんどん投げっぱなしにすれば良いというものではありません。それに、ルームではなくN:Nの関係性とのことなので、DBへの負担はO(N^2)で大きくなっていくでしょう。

結果的にLingrでは、バックチャンネルを維持する部分だけリアクターサーバを使い、それ以外の95%の部分では通常のWebアプリ(Rails)を普通のブロッキングスタイルで書くことで、メンテナンス性を維持しています。

全部をnode.jsで書くことにすると、たぶん大部分のコードは非同期のコールバックがネストしたメンテしにくい状態になるか、それを避けるためにcoroutine的にコールバックを直列で書けるライブラリに頼って使えるライブラリの選択肢を減らす(EventMachineでいうところのem-synchrony)か、という究極の選択になってくるので、あまりおすすめはできません。が、チャレンジしてみていい解決方法があれば教えて欲しい気もします。w

つらつらと書いてみましたが、おおむねnode.js向きであることは間違いないと思いますので、まずは始められたらよいのではなかと思います。

頑張ってください!

http://lingr.com/ というチャットサービスを作っている者です。

基本的に、あまりアクティビティの多くない(CPUをあまり使わない)コネクションを大量に扱う目的には、原理的にnode.jsはぴったりだと思います。

実際、Lingrでは、通常のweb部分にはRailsを使い、チャット用のプッシュを行うバックチャンネルをEventMachineというnode.jsと同じリアクターモデルで動作するRuby用のサーバで書いています(正確にいうとthin + async_sinatraです)。ブラウザの互換性を重視して現在もWebSocketsではなくComet/Long-pollで動作していますが、原理的な性能特性はどちらも同じです。

EventMachineもnode.jsも、ちゃんとFDの設定をすれば単体で10,000以上の同時接続をさばけるので、長期的に見てユーザ数が100万でデイリーアクティブ率が10%で平均滞在時間が144分だとして、保守的にみてもプロセス1個で足りるので、ほとんどの内部状態をグローバル変数で持たせることができ(シングルスレッド動作なのでハッシュのmutate atomicityなどを心配する必要もない)、非常に見通しの良いコードを書くことができます。

ただし、ある程度の規模になってくると、問題はバックエンド側になってきます。とくに「サーバーにログを残す」とあるので、おそらく間違いなくボトルネックはDBになってきます。いくら非同期で書けるといっても、DBへのコネクションは有限ですから、どんどん投げっぱなしにすれば良いというものではありません。それに、ルームではなくN:Nの関係性とのことなので、DBへの負担はO(N^2)で大きくなっていくでしょう。

結果的にLingrでは、バックチャンネルを維持する部分だけリアクターサーバを使い、それ以外の95%の部分では通常のWebアプリ(Rails)を普通のブロッキングスタイルで書くことで、メンテナンス性を維持しています。

全部をnode.jsで書くことにすると、たぶん大部分のコードは非同期のコールバックがネストしたメンテしにくい状態になるか、それを避けるためにcoroutine的にコールバックを直列で書けるライブラリに頼って使えるライブラリの選択肢を減らす(EventMachineでいうところのem-synchrony)か、という究極の選択になってくるので、あまりおすすめはできません。が、チャレンジしてみていい解決方法があれば教えて欲しい気もします。w

つらつらと書いてみましたが、おおむねnode.js向きであることは間違いないと思いますので、まずは始められたらよいのではなかと思います。

頑張ってください!