トーフサロン

Common Lisp クックブックもぼちぼちやってます。

2012-02-14

[] [erlang-questions] Erlang と BEAM の未来 (The future of Erlang and BEAM)

[erlang-questions] The future of Erlang and BEAM を翻訳。元の投稿 (StackOverflow に投稿された質問 を erlang-questions の識者に尋ねてみたもの) への Joe Armstrong からの返信。

これで Erlang に興味を持った人は「 Erlang に興味を持った人へ (id:Voluntas:20110319) 」をどうぞ。

元の投稿

エリクソン、Facebook、ゴールドマンサックスなどの会社が Erlang を業務に取り入れているのを見てきて、 Erlang に強く興味を持っていました (C++/PHP/Java の世界から来ました) 。低レイテンシで、他の言語 (私にとっては Java とか) よりもずっとすっきりして (訳注:言語仕様?) よく出来ている Erlang なら、過酷な負荷に耐えるアプリケーションを開発できる最高のプラットフォームになると思ったのです。

ところがそんな「驚き ("wow effect") 」も冷めた頃、 Erlang が最適と思われた難題の数々 (リアルタイム処理、低レイテンシの要求されるアプリケーション、並行性、耐障害性など) を解決できそうな高パフォーマンスの Java ライブラリをいくつも見つけました。中には LMAX Disruptor 並行フレームワーク (注:トレーディングシステムのプラットフォーム LMAX の並行プログラミングフレームワーク) のように BEAM では実現できないものもありそうです。

そこで質問です。高負荷に耐えるアプリケーションの開発プラットフォームとして、今でも Erlang は最適だと言えるのでしょうか? Erlang にこだわるなら、少ないリソース (OTP チーム対 JVM チーム + サポーターなど) で Erlang を他の環境に追いつかせるほうが、相当に成熟した (J) VM をさらに詰めるよりもいいのでしょうか? 本当に BEAM でこのような戦略を取り、高パフォーマンスを実現できるのでしょうか?

先に断っておきますが、私はこの議論を炎上させたくありません。純粋に答えを知りたいだけです。 Erlang が大好きで、最高のプラットフォームだと思っていて、実プロジェクトに Erlang を使って全力を尽くしたいだけです。答えてくれる人がいるなら知りたいし、私が間違っているなら訂正してくれると思います。

Joe Armstrong からの回答

短いですが、質問にお答えしようと思います。

そもそもあなたはチョークとチーズを比べています (訳注:「全然違う」を意味する例え) 。Erlang は高速なメッセージパッシングを行う言語として設計されませんでした。耐障害性を備えたアプリケーションを構築できるように設計されました。速度を目的には設計されませんでした。安全を目的に設計されました。

あなたが Erlang と比べたメッセージパッシングプラットフォームの多くは速度を優先し、安全性は二の次に設計されています。エラーを考慮しないプラットフォームが Erlang より高速だとしても、まったく驚きません。

Erlang は処理におかしな点がありそうなときにこそ能力を発揮します。コードにバグがあってクラッシュしたり、システムをオーバーロードしたり、思いも寄らない挙動に悩まされる場合です。

Erlang の考え方は他の言語と全然違います。

Web サーバを例としてみましょう。これまでの考え方では、一台のマシンに一つの Web サーバがあるとすれば、タスクが要求されるたびに OS のプロセスを生成するか (安全) 、すべてのセッションを同じタスクで管理するでしょう (速いけど安全ではない) 。*1 Web サーバは安全上の理由で OS のプロセスを使います。ユーザのセッションそれぞれにプロセスを割り当てれば安全ですが、かなり遅くなります。

もし Web サーバのソースコードに稀に発生するエラーがあったらどうなるでしょうか? ごく稀にしか現れないエラーだとします。このエラーはすべてのユーザのセッションに影響するのか、エラーの発生したセッションのみに影響するのか? おそらく Web サーバが潰れたらセッションもすべて潰れるだろうと思います。

Erlang なら Web サーバをどう実装するのか? 表面上は他の Web サーバと似ていますが、ユーザのセッションを 2000 抱えた Erlang システムは、 2000 のセッションを管理する一つの Web サーバではありません。それぞれが完全に独立した Erlang プロセスが 2000 あり、一つ一つが完全に独立した Web サーバとして動作します。

つまり Erlang では 2000 の Web サーバがあり、それぞれユーザのセッションを一つだけ抱えて動作します。これまでは一つの Web サーバで 2000 のセッションを抱えるのが普通でした。

話を戻します。あるセッションでごく稀にしか発生しないコード上のエラーに遭遇したらどうなるでしょうか? Erlang なら一つの Web サーバだけが落ちて、他の Web サーバはそのまま動き続けます。 2000 のセッションをまとめて管理する Web サーバは高速ですが、すべてのセッションが死にます。

では、速さと安心のいずれかをお選びください。超高速な Erlang が欲しいと言うなら間違いです。そんな Erlang は安全ではありません

エラーチェックとエラーからの復帰にはコストがかかります。ただで手に入るものなどありません。

時折「Erlang っぽいモデル」でより高速だと言われるメッセージパッシングシステムを目にします。

ですがそう言ったシステムは安全ではなく、「Erlang っぽいモデル」は高速なメッセージパッシング以外の意味も含んでいます。

Erlang は耐障害性を備えたソフトウェアリアルタイム分散システムとして、なおかつ動的にコードを差し替えられるシステムとして、設計の意図通りにうまく動いています。これにわずかでも近いシステムがあるとは聞いたことがありません。

上辺だけのシステムは山ほどありますが、障害に強いシステムを作るに値するシステムはありません。

*1:原文は "the web server might spawn an OS process for each incoming task (if it wants safety) of it might handle all sessions in the same task if it wants speed but no safety" ですが、 "or" の間違い?