InfoQ の "EventMachine: Fast and Scalable Event-Driven I/O Framework" を訳してみた

by tanabe on January 28, 2009

InfoQ の "EventMachine: Fast and Scalable Event-Driven I/O Framework" には「EventMachine: 高速でスケーラブルなEvent-Driven I/Oフレームワーク」という公式な邦訳があるんだが、これが何度読んでもよく意味がわからない。

もちろん、ぼく自身がイベントドリブンというものをよく理解していないという問題が大きな壁になっているのは間違いない。でも、そもそもよく理解していないから読みたいわけで、困ってしまった。EventMachine の開発者 Francis Cianfrocca のインタビューもあり、内容はよさそうな気がする。

で、何度か読むうちに「これは原文あたったほうが早いんじゃないか」と気付き、ちまちまと理解を進めながら訳したので公開しておく。

全文訳は公式のものがあるので開発者インタビューを中心に重要なところをまとめる。

誤りのご指摘大歓迎。特に技術的な意味での妥当性に不安があるので「これ、おかしくね?」とか言ってもらえると大変助かります。


The key technical reason to use EM is because it enables a programming model that avoids threads. Threaded programming is of course a very well-known model, especially for network servers, but it has some very deep problems. There is a relatively small class of problems which are a good match for the threaded model. Network servers happen to be one of them, because it's usually possible to construct a non-overlapping working set for each request. But of course it's very difficult to get a threaded program 100% correct if it has any shared state between threads, or if it relies on operations to be properly sequenced across threads. And in Ruby, there's the additional problem that threading is very expensive.
EM を使う技術的な理由のポイントは、スレッドプログラミングを避けられるという点です。もちろんスレッドプログラミングはよく知られたモデルです。特にネットワークサーバーにおいてはそうでしょう。ですが、いくつかの非常に深い問題もはらんでいます。スレッドモデルに適した比較的小さな課題というのもあります。通常リクエスト間での状態の共有を必要としないネットワークサーバーはその一例と言えるでしょう。しかし、ひとたびスレッド間での状態の共有を必要とするプログラムを書くとなったり、スレッド間で一連の手続きを正しい順に実行しなければならなくなったりすると、100%正しいプログラムを書くのは非常に困難になります。そして Ruby にはスレッドが高価だという問題もあります。

てなとこかな。

A lot has been written about the fact that event-driven programs are not theoretically any faster than threaded ones, and that is true. But in practice, I think the event-driven model is easier to work with, if you want to get to extremely high scalability and performance while still ensuring maximum robustness. I write programs that have to run for months or years without crashing, leaking memory, or exhibiting any kind of lumpy performance, so in practice, event-driven programming works better. Now, here's the problem with event-driven programming: you have to write "backwards." A threaded model stores your program state (inefficiently) in local variables on a runtime stack. In EM you have to do that yourself, which is very unintuitive to programmers who are used to threads. This is why I'm interested in fibers, because it opens the possibility of writing what looks to the programmer like blocking I/O, but still is evented and uses no threads.

邦訳の最後がいまいちよくわからんので原文に当たる。

イベントドリブンプログラミングの問題も紹介しましょう。あなたは逆向きにプログラミングをしなければなりません。スレッドモデルでは状態を(効果的ではないのですが)ローカル変数に入れてスタックに積めます。EM ではこれを自分自身で行う必要があります。これはスレッドに慣れたプログラマにとっては直感的でなく感じます。そして、この点が私が Fiber に興味をひかれる理由でもあります。スレッドを使わずイベントドリブンなままで、まるでブロッキング I/O のようにプログラムを書くことができる可能性が開けるからです。

か。ほうほう。でも、原文読んでも "backwards" の意味がよくわからない。スレッドモデルに対し、backwards なの?

でありがたいことに具体例に続く。(でも正直何が backwards かはいまだによくわかっていない。。)

Think of an HTTP server. With threads, you simply read the socket and block until all the data has been retrieved from the remote peer. With events, you get the data as soon as it appears, with no waiting and no scheduling overhead-But it may not be complete! Your program has to detect that it hasn't yet received enough data to interpret the request, and it needs to store the partial data. But the next event that your program handles will possibly contain data for a different connection, so you have to keep all of this straight. The threading abstraction is a very heavyweight way of keeping those working sets separate, so it makes the programming task arguably more intuitive. But the evented model is not really so hard to learn. Nevertheless, I think this is the biggest barrier to wider use of event-driven programming.

スレッドモデルだと、

With threads, you simply read the socket and block until all the data has been retrieved from the remote peer.

単にソケットを読み込んで、リモートから送られてきたデータがすべてそろうまで待たせれば(ブロックすれば)いい。ってこと。

イベントだと、

With events, you get the data as soon as it appears, with no waiting and no scheduling overhead-But it may not be complete!

データが送られてきた端から即座に受け取る。待たされることはないし、スケジューリングのオーバーヘッドもない。でも、データはすべてそろっていないかもしれない(笑)

なんとも、わかりやすい。

イベントモデルの解説は続き、

Your program has to detect that it hasn't yet received enough data to interpret the request, and it needs to store the partial data. But the next event that your program handles will possibly contain data for a different connection, so you have to keep all of this straight.

ふむふむ。

イベントモデルなアプリケーションがしないといけないのは、

  • 解釈して実行するのに十分なデータが送られてきたかどうかの判断

  • 不十分であれば送られてきた部分的なデータを貯めておくこと

なのか。

一方で、次のイベントとして処理されるのは別のコネクション(別もののリクエスト)からのものでありえるので、これらを続けて実行できるようにしておく必要がある、と。

で、

The threading abstraction is a very heavyweight way of keeping those working sets separate

スレッドモデルはこのコネクションごとに状態を管理しておくための非常に重たいやり方であり、その恩恵としてプログラミングがより直感的になる。

But the evented model is not really so hard to learn. Nevertheless, I think this is the biggest barrier to wider use of event-driven programming.

でも、イベントモデルを学ぶのもそんなにむずかしいわけじゃないよ。まぁ、それはともかく、これが EM なプログラミングが広く使われるにあたっての一番の壁だと思ってる。

Now one of the things that EM does is to wrap up the standard protocols so that all of this is largely hidden from the programmer. Unlike low-level libraries like libev, which provide only a reactor core, EM seeks to provide robust implementations for all the standard network protocols, for example, email. EM includes a well-written handler for both the client and server side of SMTP. So an EM programmer only has to write code to handle events associated with complete email messages. There's no need to touch the underlying protocol. But still you have all the other benefits of the evented model (high speed, high scalability).

EM のやっていることとして Email の例があるので、具体的なところだけ訳す。

EM includes a well-written handler for both the client and server side of SMTP. So an EM programmer only has to write code to handle events associated with complete email messages. There's no need to touch the underlying protocol. But still you have all the other benefits of the evented model (high speed, high scalability).

EM は SMTP プロトコルのためのよくできたサーバとクライアントのハンドラーを持っているので、EM プログラマは Eメールの受信に関するイベントを扱うだけでよくて、SMTP についてはケアする必要がない。そして、それでも(高速でスケーラブルだという)イベントモデルによる恩恵はすべて得ることができる。

というような意味か。

ノンブロッキング IO だという利点はわかるんだけど、どういった利用があるのかがイメージついていない。Thin とかで実装を見たほうがイメージしやすいのかなぁ。

あとはこの辺読んで基礎をちゃんと学べってところですね。はい。

UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI
W.リチャード スティーヴンス
ピアソンエデュケーション
売り上げランキング: 74470


この記事へのコメント
backwardsの意味は過去に遡ってという意味ではないですかね。
複数の過去のリクエスト用のバッファに追記するという意味で。
Posted by ゆーすけ at October 30, 2009 11:24