node.js vs Erlang (ネタ)

ついぞ最近node.jsなんてのがでて、繁華街のあちこちでチヤホヤされてる。そんなときに、モヒカン族Erlang村(erlang-questions)に「node.jsってどうなの?」的燃料が投下されたわけですよ。これは炎上しそうだ…と追いかけてたら、ネタどころか案外真面目なハナシばっかりだったのですが。まずは真面目に問いかけをする純朴な成年(想像)。

Erlang好きだし使ってるんだけど、Erlangとnode.jsてそれぞれどういうジャンルがすごいの?RabbitMQとかejabberdみたいなのつくろうとしたらどうなるの?簡単なチャットサーバーつくるくらうならnode.jsのが断然簡単だよね?分散システムで使うなら断然違うとか?
Ulf Wigerによると、ブロックする関数の問題を簡単に解決してくれるとか書いてあるみたいだけど (link)」

おっお。素直な質問。これはみんな釣られるんじゃねーのか?!

「ていうかnode.jsて何に使えるわけ? RubyとかPythonじゃなくてJS選ぶ理由がワカンネ」
Erlangが解いてくれる問題を何一つ解決してくれないよね」
Erlang使えるなら別にそれでいいじゃん」

さあ、盛り上がって参りました…!! ここでJoe Armstrong*1登場!!!ぼくの中では「ざわ…ざわ……」が完璧に再生されていました。

「node.jsがどうして作られたのかって?JSでサーバー書きたいだけでしょ?
Erlangは違うんだよ、キミ。
soft real-time fault-tolerant systems that could be upgraded without taking them out of serviceのためなんだよぉ〜

  • 各プロセスに張り付いた高速なGC
  • コードを適切に変更する(古いコードと新しいコードが共存できたりするよ)
  • 直交したエラー検知のメカニズム (catch-throw/links/ ...)
  • プラットフォームに依存したいエラー検知と回復(ie to make something fault tolerant needs at least 2 machines, think the case when one machine crashes - the second machine must be able to take over)

 他にも分散プリミティブとか、分散ベータベースとかね、いろいろ。node.jsにそんなのあるの?よく知らないけど、node.jsってサーバー壊れてもtake overとかしてくれないでしょ?
故障モデル、コード変更、コード移動、無停止アップグレード、こういうのって24x7でダウンタイム0のシステムだと大事だよね。こう言うのを最速で作りたいならどう考えてもErlang。node.jsじゃないよね」

うんうん。さすが教祖様はお説教のありがたみが違う。

「node.jsってPythonのTwistedだったりRubyのEventMachineみたいなもんだよ」
ErlangBMWの重量級ラインナップみたいなもんなら、node.jsってVespaみたいなもんだよね。JS知ってる人には便利だけどOTPとかそういうスッゲーのはないよね。JSてメジャーな言語だからみんな気になってるだけでしょ」
「Nodeはまー、非同期イベントドリブンふれーむわーくってとこかな。ややこしいコールバックの世界*2だよ。Erlangはそういうの抽象化して、プロセスとかメッセージとかにして同期っぽく見せてくれるから楽(もちろん裏側は非同期で動作してるんだけど)。リクエストと状態を合わせたのがErlangプロセスなんだけど、それって真ん中のI/Oハンドラーから丁寧に見つけて渡してやるより楽でしょ。
まぁI/Oの問題がないならNodeでもいーと思うけど。」
「いやーそもそもね、JavaScriptが良い言語で、サーバーの世界にも持ってこれたらいいよねとか思うヤツらが全然理解できねぇ」
「別にJavaScript好きでもなんでもないけどさ、不思議なんだよね。JSでコード書くときって、結局オブジェクトのイベントにコールバック貼りつけて非同期なプログラミングするわけでしょ。これってサーバープログラミングとそっくりだよね。JS使うのってある意味自然なことなのかも」

…おや? 炎上するかと思ったら建設的な方に話が進んでいるよ?? ツマンネ…と!なりかけたところにッ!ここで再びJoe Armstrong登場ッッッ!!

「だからさー、わっけわかんね。なんでみんなYaws vs ApacheとかErlang vs node.jsとかいうわけ。比べ方を間違ってる。
 ErlangのWebサーバーってのはね、1コネクションにつき1プロセス立ち上げるわけ。わかる?100Kのコネクションがあったら、100KのWebサーバーが立ってるわけ。そん中のいっこくらい死んでも何ともないのがErlang.
 Apacheは違うよ。プロセスがいっこ死んだらおおごとだからね*3

さすがッ!!教祖様、ナナメ上から袈裟斬りに一刀両断ッ!!その発想はなかったわ。

Erlangて何十万行もあるレガシーコードを走らせるためのものだよねー。ランタイムにそういうのゴニョゴニョできるのはこれでしょ」

そうだねー。コンパイラ型推論がいつまでたっても導入されないのは某E社の既存資産のためだよね絶対。と思っていたら、もっとスゲー話が。

Erlangに出会うまで、サーバーサイドJSをガチで5,6年書いてたよ。stringをevalして無停止アップグレードとか、20台くらいの分散システム(もう100台くらいが中央サーバにつなってたり)で、TCPとかHTTP使ってたり、冗長化してfault-tolerantだった。結局、Erlangアプリケーションの劣化版みたいになっちゃってたけど、割とよく動いてた。
 で、2007年にErlangを知ったんだよね。自分たちがやってきた問題を全部解いてくれてんじゃん、とか思って。結局性能よりも故障耐性なんだよね。ぼくらのJSエンジンはWindows Script Hostだったんだけどそんなに安定してなかったしメモリが漏れてたりで、20台x7プロセスで、一週間に10~20くらい落ちてた。問題は速度じゃなかったんだよね。結局CPUじゃなくてネットワークがいつもボトルネックだった。WSHも数百万トランザクションは数日で捌いてたんだよね(僕らも驚いたけど)。WSHにマルチスレッド機能なんて存在しないもんだから、いろいろゴニョゴニョやってマルチスレッドで動くようにしたんだけどまー予想通りムズカシイ。んで、自分でスケジューラー書いてタスクにタイムスライス切ったりした
 でも、Erlangは僕たちがこれまで書いてきたものを全部持ってたんだ。Erlangじゃない言語で似たようなもの作った身としては、これ以上のものはないよね。あのシステム書き始めたときにErlang/OTP知ってたら、JSでgen_server的なもの作ってたと思う。Node.jsはWSHからするとマルチタスキングを始めとして本当に小さな一歩だけど、Node.jsでサーバーサイドなアプリケーションを作り始めたら、結局Erlang/OTPみたいなのを作ることになると思うよ
 とはいえ、JS老兵としては、どうなるのか気にもなる。新しい仕事でNode.js使うかどうかも考えてみたけど、まだいらない。(中略)JSで残念なのは言語そのものじゃなくてWebページのDOMの扱いだよね。クロージャとかobject contextとか性能のはなしとか、今ではみんな知ってるからいいけど、ちょっと前まではすごくマイナーだった」

ざわっ… JSでそこまでやってる人がいたんだ…っ!しかもWindowsで! ちゃんとしたサーバー作るなら、そこまでやらないといけないよね。V8とかSpiderMonkeyってその辺どうなってるんだろう(知らずにいうけど)。

「ぼくもJS→Erlangなクチだけどnode.jsは非同期にしてるくせにエラーん扱いが割と適当で、コミュニティもそんなに問題視してない。だからまだオモチャだよね
 とはいえNode.jsだと5分でHello worldまでいったけど、Erlangはそうはいかなかった。ビルドツールも微妙で決定版がないし、パッケージ管理もアレだし、初心者に優しくないよね。OTPチームは忙しいんだからコミュニティで何とかした方がいんじゃね?」

ここでこのネタの発端のひとつになったErlang vs node.jsの記事を書いた人が登場

「やっぱお手軽さじゃあNode.jsには敵わないよねー。お手軽なので人が集まってこれから発展していくと思うよ。大抵の人はErlangみたいに本気なものじゃなくて、お手軽なので十分だからね
 ニッチになっていくのは残念だけど、本気なシステムの需要がなくなることはないから、Erlangスキルしかないからといって食っていくのに困るとは思わないし」

ここでUlf Wiger*4登場

「まあErlangちょっとかわってるからねー。
Also, the advantages of Erlang are perhaps not so readily apparent, as principles for massive concurrency and the issues of exception flows and exception handling in concurrent systems are not part of the regular curriculum. Add to that the "pioneering nature" of much in the Web space, and you will have a large group of people who go for the low-hanging fruit, and defer any problems of scale, robustness and complexity until later.
It will be a combination of knowingly deferring some problems, and of not even realising what lies ahead. I don't necessarily view this as a bad thing. Much innovation might have been stifled by too much knowledge of the difficulties lurking around the corner.」

ちょっと日本語に訳すには…アレなので。ご自分でこのニュアンスをそこはかとなく味わっていただければと思います。

触ってもないのにいいますが、なんでnode.jsてあんなに持て囃されているんでしょか。サーバーとクライアントが同じ言語で書ける?ライブラリを共有できることがすごいんでしょか。確かにWebプログラミングってやってることはすごく単純だけど(サーバー側のディスクに書かれているデータをクライアントから操作する)、ブラウザをはさんだりHTTPはさんだり、SQL書いたりUI工夫したりといろいろと錯綜した技術だと思います。だから面白いところが沢山あるのですが。その複雑な部品のひとつがJSなわけで、HTMLもCSSSQLJavaScriptで書けるようになるんだとしたらnode.jsもいいかなぁとは思いますが、ぼくが触ることのはないのでしょうきっと。
いや、ぼくがJS書けないから僻んでいるだけなんですがね(えっ

*1:Erlang創始者。RubyでいうところのMatz

*2:訳注:本文にinverted controlって用語があったけど何だろう?

*3:訳注:それに巻き込まれて死ぬひとが沢山いる、という意味(たぶん)

*4:Erlangグル。Rubyでいうところの笹田耕一さん…かな?