Rubyのまつもと氏も注目する話題の言語

twitterブームの陰で注目を集める“Erlang”

2007/04/27

 “twitter”がブームだ。140バイト以内の短いメッセージで“現在進行形”の自分のステータスをほかのユーザーとシェアするだけのオンラインサービスだが、本国の米国はもとより、日本でも非常な人気を集めている。Alexaでアクセス数の推移を調べると、今年に入ってから本格的にブレークしている様子が分かる。4月22日にはニューヨークタイムズもtwitterと、サンフランシスコ在住の創業者2人を記事で取り上げている。

erlang01.png Alexaによるtwitter.comのアクセス数推移グラフ

twitterのコミュニケーションツールとしての新しさ

 twitterに参加してみると、チャットやメール、SNSといった、既存のコミュニケーションツールのいずれとも異なる、不思議なつながり方が新鮮で楽しい。熱心にメッセージを更新するユーザーを見ていると、CUSeeMe、ICQ、mixiなどが登場したときに人々が示した熱狂に近いものを感じる。

 twitterでは、数時間や数分スパンで自分のアップデートを、友人や知人に“押しつけがましくない作法”で送る。ブラウザに向かって「腹が減った」、「JavaScriptのセミコロンでハマってた」、「コピー機が故障してプレゼン資料出せない」、「イチローの試合観戦中」などと打ち込めば、自分のメッセージをフォローしているユーザーの画面に、そのメッセージが表示される。基本的にメッセージは1対Nであり、誰か特定の人に向かって送るものではない。双方向のやり取りはプライベートメッセージを使うか、メールなど別の方法を使うことになる。

 それとなく話題を振ったり、誰にともなく質問を投げてみたり、独り言のようにランチの誘いを発したりと、使い方はいろいろ。反応も、あったりなかったりだ。メッセージを見た人は、メールのように返信の義務感にせかされることもないし、チャットのようにコミュニケーションに始まりも終わりもなく、連続性すらない。

twitterは、このままスケールするか

 twitterの流行は興味深い現象だが、ここで私が書こうと思っているのは、twitterそのものの話ではない。twitterの行く手に控えている“C10K問題”だ(参考リンク:Web2.0の先にあるC10K問題)。現在、twitterでは秒間4000ものメッセージをリアルタイム処理しているというが、果たしてこのままユーザー数が増え続けたときに、システムは実用的な時間で反応できるのか。そんなことが、最近Web開発者の間で話題になっている。

 twitterの開発に携わっているブレイン・クック(Blaine Cook)氏は“Big Bird(scaling twitter)”と題するプレゼンテーションの中で、twitterがRuby on Rails(RoR)を使っていることを明かしている。問題は「RoRがスケールするか」ということになるが、クック氏は対策として、こまめなインデクシングによるデータベースの最適化や大規模Webアプリケーション作成時の定番ツール、“MemCached”で分散メモリキャッシュを多用しろとアドバイスする。大規模なSNSではもはや常套手段となった感もある手法だ。ただし、RoRはこうしたことを自動でやってくれるわけではないので、該当するコードの部分に、すべて手で対応コードを埋め込めとクック氏はいう。

 クック氏の結論は「RoRはスケールする(火曜日にシステム停止したけどね)」という皮肉なもので、これ以上複雑なシステムを作るならRoRでは対処しきれないとしている。

注目を集める言語、Erlang

 twitterでは、メッセージングシステムに“ejabberd”を使っているという。これは“Erlang”で書かれたIMサーバだ。オープンなIM標準規格のJabberに対応している。また、クック氏がプレゼンテーションの中でRoRの代替として挙げている候補の1つ、“RabbitMQ”も、Erlangで書かれたメッセージングサーバだ。

 Erlangが、Web2.0サービスにおけるスケーラビリティという課題に対する有効な答えではないか――。そう考え始めている人が増えているようだ。Erlangの生みの親であるジョー・アームストロング氏は、Erlangのメリットを、ずばりこう述べている(参考リンク)。

Your Erlang program should just run N times faster on an N core processor.

(あなたが書いたErlangのプログラムはNコアのプロセッサならN倍速く動くはずだ)

 コアの数を増やすだけで自動的に、ほぼリニアに速くなるというわけだ。これは普通の処理系ではありえないことだ。

 Erlangは並列処理に適したプログラミング言語で、1987年に登場し、1998年にはオープンソース化されているので新しく登場した言語というわけではないが、時流に乗る形で、現在にわかに注目を集め始めている。Rubyの開発者として知られる、まつもとゆきひろ氏も、4月18日の“「次」の言語”と題したブログのエントリで「次にくるトレンドは『関数型』と『並列』。両方を押さえたErlangが本命。歴史も信頼性もあり、知名度上昇中」と、次にメジャーになりうる言語の本命にErlangの名前を挙げている。

 Erlangは、もともとエリクソンが開発し、テレコム分野で実績を重ねてきた言語だ。言語名のErlangは、デンマーク人技師のAgner Krarup Erlang氏の名前にちなんで付けられているが、エリクソン(ERricson)の言語(LANGuage)という二重の意味が込められているという(参考リンク:Wikipedia解説)。発音は英語圏では「アーラング」や「アーラン」が多く、生まれ故郷のスウェーデンでは「エアラング」に近い音で発音されるようだ。

マルチスレッドプログラミングは複雑すぎる

 C10K問題は、小さな仕事を要求するクライアントが数万台規模でサーバにぶら下がると現在のシステムは破綻するというものだった。例えばHTTPサーバのApacheは、リクエストを受けるたびに子プロセスをフォークして処理をこなすというUNIXに古くからある一般的なサーバの実装となっている。実装は容易だが、プロセスを丸ごとコピーするため起動のオーバーヘッドが大きいし、メモリ消費量も多い。プロセス数が多くなってくるとOSのタスクスイッチのコストも無視できない。

 一方、プロセッサのコア数は今後も増加しそうだ。インテルやAMDのプロセッサのコア数は2、4、8個と増え続けているし、サン・マイクロシステムズのUltraSPARC T1では8つのコアで、各コアごとに4つのスレッドの並列処理ができる。数年後には数十のコアを最大限に生かす、オーバーヘッドの少ない並列処理のプログラミングモデルが求められているわけだ。

 現在、並列処理のために広く使われているテクニックはマルチスレッド化だが、メモリ空間を共有しないマルチプロセスと異なり、同一プロセス中で複数のスレッドが並列して走るマルチスレッドでは、かなり注意深いプログラミングが必要になる。グローバル変数やスタティック変数といったスレッド間で共有しているメモリに、どのスレッドからでもアクセスできてしまうからだ。

 どのスレッドが、どういうタイミングでメモリを書き換えるかを、プログラマが常に頭の中で追いかけるのはきわめて困難だ。バグが忍び込む余地が大きい。たとえ一見動いているように見えても、特定の条件でエラーが起きる可能性を排除するのは事実上不可能だ。

 こうした問題に対処するために、多くのスレッドライブラリでは、スレッドから呼び出してもよい“スレッドセーフ”な関数を用意したり、OSのセマフォに似た“ミューテックスロック”といった排他処理用のロック機構を用意している。ミューテックスを使った排他制御でデータの一貫性を保つことはできるが、複数のスレッドが同時にデータに複雑な順序でアクセスした場合にも常に一貫性が保たれるようにするのは熟練プログラマにも難しい。

 カリフォルニア大学バークレー校で電子工学と情報科学を教えるエドワード・A・リー教授は、「The Problem with Threads」の中で、マルチスレッドは、これまでわれわれが慣れ親しんだプログラミングモデルであるシーケンシャル処理にあった理解可能性(understandability)、予測可能性(predictability)と、決定論(determinism)を損なうとし、並列処理のプログラミングモデルとしてのスレッドは捨てるべきだとまで言い切っている。「自明でないマルチスレッドプログラミングというものは、人間には理解不能」だからだ。

 ゲーム業界のプログラマも、マルチスレッドプログラミングで悲鳴を上げている。Unreal Tournamentシリーズで知られる米Epic Gamesのティム・スウィーニー(Tim Sweeney)氏は、「The Next Mainstream Programming Language: A Game Developer’s Perspective」と題したプレゼンテーション資料の中で、1万個にも及ぶゲーム内のオブジェクトが、1秒間に30回もの高頻度で更新され、そのたびに各オブジェクトが5〜10個のほかのオブジェクトに影響を及ぼすという仮想世界について述べている。スウィーニー氏によれば、GPU上のシェーディング処理などは、専用言語で高度に並列化されているが、CPUのほうの処理の並列化は、独自に設計した非対称で複雑なマルチスレッド処理によっているという。慎重なプログラミングを行っているというが、これはきわめて困難で、生産性や保守性の足かせになっているという。

メッセージ通信による並列処理

 スウィーニー氏は、今後はメモリ上で相互にプロセス同士がメッセージ通信を行う“Composable memory transactions”のようなプログラミングモデルに移行するべきだと述べている。これは、より抽象度の高い概念では“アクターモデル”と呼ばれているプログラミングモデルで、プログラムの基本となるユニットが、すべてアクターとして振る舞う。アクターは、ほかのアクターにメッセージを送ったり、アクターを生成したり、次のメッセージを受信したときの動作を変更するといったことだけができる。これはちょうど人間同士の仕事の進め方のようなものだ。人間同士の脳の一部は共有されていないため、コミュニケーションが面倒だったり、エラーが起こったりするが、並列処理では人数に比例したパフォーマンスを得られる。誰かほかの人の脳の状態に関係なく仕事が進められるからだ。

 こうしたプログラミングモデルが、たとえ共有メモリを使ったマルチスレッドのプログラミングモデルよりも遅く、オーバーヘッドが2〜4倍になるとしても、N個のコアのプロセッサでN倍に近いパフォーマンスが出るならば、結局のところはその方が有利だという。またコードの生産性が10%上がるのであれば、喜んでパフォーマンスを10%を犠牲にする、とも述べている。

Erlangはメジャーになるか

 言語処理系にマルチスレッド機能を追加するにはライブラリの追加や、言語仕様への少しの修正で済むケースが多い。このため、既存の処理系はマルチスレッドをサポートして、デュアルコア時代にも高いパフォーマンスを発揮できるようにしているわけだが、今後、メニーコア化が進むことを前提とすれば、もはやドラスティックに並列処理のプログラミングモデルを変えるべき時代が来ているのかもしれない。

 Erlangは、シンプルなメッセージ通信によるアクターモデルを採用した並列処理に強い言語だ。オーバーヘッドが小さく、1台のサーバ上で2000万プロセスを並列で立ち上げてメッセージを送受信させるベンチマークを行った人もいる(参考リンク)。また、もともと高信頼性が要求される通信分野で使い込まれてきたため、エラー耐性に強いという特徴もある。特定のアクターに異常が発生した場合、監視役のアクターが当該アクターに対して何らかのメッセージを送るということもできる。

 前出のエドワード・A・リー教授は、ErlangやAdaのような、スレッドに代わる並列処理のプログラミングモデルが、かなり以前から存在しているにもかかわらず根付いていないのは、これらの言語が、人々が慣れ親しんだC言語のような文法と異なるためだという。すでにデファクトとなった言語を置き換えるのではなく、そうした言語に、直接言語仕様に影響を与えない形で新たな文法を追加するのが正解ではないかという。

 リー教授がいう通り、Erlangが一般のプログラマに受け入れられるとは考えづらい。しかし、Web2.0の世界でスタートアップを考えているような人々――、誰よりも先に、きわめて高いスケーラビリティがあり、保守性や信頼性の高いシステムを構築しようという人々の間では、Erlangが使われるようになっていくのかもしれない。また、長い目で見れば主流の言語にも、並列処理の枠組みが徐々に採り入れられていくのだろう。

関連リンク

(@IT 西村賢)

情報をお寄せください:



@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)