Subscribed unsubscribe Subscribe Subscribe

サーバサイドJavaScriptは何故流行することになったか。

どこかで書いたもののリライト。

何故JavaScriptなのか?

JavaScriptがサーバサイドで使われるようになったのは、おそらくWebSocket対応によるC10K問題が現実的になったからだろう。
これは昔から知られている問題で、Apacheのような普通のWebサーバだとスレッド毎にメモリを消費するマルチスレッドモデルだが、スレッドスタックのメモリサイズはサーバ毎に固定のため、コネクションが固定化されるWebSocketモデルでは本当に問題になるのだ。
スタックサイズがどこで決まっているのかというのを具体的にいうと、以下のstacksizeの箇所である。後は、ApacheなどのWebサーバの設定にもあるが。

user$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 2560
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 709
virtual memory (kbytes, -v) unlimited

TheC10kProblem - 「C10K問題」(クライアント1万台問題)とは、ハードウェアの性能上は問題がなくても、あまりにもクライアントの数が多くなるとサーバがパンクする問題のこと
これを解決するにはイベント駆動型モデルにするしかなく、nginxはそうした問題を解決するためのWebサーバであるが、この上で動作させるには、同様のイベント駆動型言語の方が望ましい。
そのため、サーバサイドでJavaScriptを動作させるというのが流行することになった。

JavaScriptは、ノンプリエンティブマルチタスクという、まるでWindows3.1のようなアーキテクチャで動作しており、10年前には主にクライアント側の性能問題により個人的には酷い目にあった記憶があるが、あれから10年経ち当時非常に苦労したイベント駆動型のメリットが活かせる箇所がついにやってきたということだろう。

因みに、C10K問題は嘘ではなくて、実際スループットが10000tpsを超えると極端に辛くなる。
普通、サーバのボトルネックはCPUやメモリの限界だと思う人が多いだろうがこのレベルになるとそんなことは全然なくて、まずカーネルパラメータのチューニングが必須なのは良いとしても、TCPセッションのNIC引き当てでパケットドロップしたり、メモリのバスネックに引っかかったりする。
大体の場合、NIC周りでどうにもならなくなることが多い。GbE使い切るのは稀。

補足、またはセッション管理時の問題

また、Webサーバだと割とセッション管理を利用することが多いだろうが、セッション情報をノード間レプリケーションを使っていることが多くて、それだとスケールアウトする際に、レプリのリバランスが問題になって、単純スケールアウトほどの性能が出ない。
例えば、10000tps/1台でるサーバだったとして、このような構成だった場合、2台に増やしても20000tpsを捌けることはない。大体15000くらいであろう。勿論更に台数を増やすと、リバランスはどんどん問題になっていく。これを防ぐためには、セッション管理用のメモリDBを別に構築するか、セッション管理を使わなくするというどちらかの方式しかない。このレベルのスループットではL7スイッチは使えない。L7スイッチが使えるのは精々3桁tpsである。
いくらRestfulなAPIだからステートレスだと言っても、認証問題が出てくると、セッション情報を持たざるを得ないであろう。普通、そこまで冗長性のことを考えて、アプリケーション設計できないしね。
ここでも安易にスケールアウトさせることができないC10K問題が問題となり得る。