Previous month:
September 2012
Next month:
November 2012

今週の週刊 Life is Beautiful:10月30日号

今週のメルマガ「週刊 Life is Beautiful」の配信準備が整ったので、内容を簡単に紹介する。

今週のざっくばらん

AJMax

ブログでも告知をしましたが、node.js 向けのマイクロ MVC フレームワーク AJMax をオープンソースとして公開しました。AJAXを駆使してブラウザー上で "on-page application" を実現するための仕組みです。HTML5 時代のウェブ・アプリケーションのアーキテクチャに関しては、3〜4年前からさまざまな研究をして来ました。2009年にブログで書いた「RESTful MVC アーキテクチャの話」というエントリーを書いたのもそのころです。それ以来、実際にいくつかの one-page application を立ち上げて来ましたが...

Windows RT

Microsoft が Windows RT を搭載した Surface を発売しましたが、この Windows RT の位置づけがとても分かりにくく、市場で混乱が生じています。見た目は Windows 8 と同じだし、Windows 8 を搭載した タブレット・パソコンが OEM メーカーから発売されていることを見れば、Surface も単に Windows 8 を搭載したタブレット・パソコンの一つだと勘違いする人も多いと思います。しかし、実際には Windows 8 と Windows RT は「全くの別物」だと考えた方が...

私の目に止まった記事

 Make More Stuff, and Make It Thinner

Apple が噂されていた通りに iPad mini を発表しましたが、確かに脅威的なのは、この記事にも書いてある通り、同時に新型の iPad、iMac、 MacBook も発表することが出来る Apple という会社の底力です。業界関係者によれば、9月に iPhone5 の発表をした時に同時に iPad mini の発表が出来なかったのはパネルの調達が...

Ballmer and Dell Talk Windows 8 and Surface Tablet in Joint Interview

Microsoft が Surface でハードウェアビジネスに進出したことは、Apple に対抗するために必要な戦略でしたが、これまで Windows パソコンを作って来た Dell や HP にとっては今までパートナーだったはずの Microsoft が自分たちのビジネスに踏み込んで来たことに相当します。これに関して、Microsoft と Dell/HP の間でどんな話し合いがされたのか...

 Wow, Facebook Is Already Making $3 Million A Day On Mobile Ads

Facebook の将来はモバイル端末からの広告収入を上げることが出来るかにかかっている、という話は前にもここで書きましたが、第3四半期の結果を見る限り、この記事に書かれている通り、「期待以上の結果」と言えると思います。私も Facebook へのアクセスは、パソコンとモバイルとが半々ぐらいですが、最近徐々にモバイル側での広告を...

Why Twilio points to the future of app development

Voice Over IP(VOIP) の実現方法に関して調べていたところ候補の一つとして浮上してきたのが、この Twilio でした。単なるインターネット上の VOIP サービスだけでなく、既存の電話網との接続を含めた網羅的なサービスを提供している会社です。この記事にも書いてある通り、広い意味では "Cloud Computing Service" もしくは "Software as a Service (SAAS)" の一つではありますが...

Apple’s Online Radio Service to Challenge Pandora in 2013

アップルが Pandora に対抗するインターネット・ラジオ型の音楽のストリーミング・サービスを始めるという噂は少し前から出ていましたが、それを追従する形でのBoomelangによるリーク記事です。Appleとミュージック・レーベルとの間の交渉が大詰めに来ており、11月には契約が成立し、2013年の第1四半期にはサービスが開始される予定だと書かれています。ここまで細かな情報が出て来ると...

UIEvolution 起業ものがたり(5): Steve Ballmer

 Steve Ballmer の秘書さんから指定された通り、金曜日の朝7時に Microsoft キャンパスのすぐ近くにある PRO Sports Club に行くと、すでに Steve は私のことを待っていました。二人だけでゆっくりと話すのに適切な場所を見つけて座ると、Steveが「こんな時間に呼び出してすまない」と言ってから、私の返事も聞かずに「Brad のところに行くそうだな」と本題に突入します...

node.js 入門(1):なぜ node.js なのか

何年か前に、インタビューで「プログラマーを目指す学生が最初に勉強すべき言語は何だと思いますか?」と質問された時に、迷いながらも「JavaScript」と答えたことを覚えています。今なら迷わず、JavaScript だと答えます。それどころか「node.js こそが最初にプログラミングを勉強するのに最適な環境」と...

読者からのご質問・ご意見コーナー

今週の質問です。

エンジニアの健康維持に関してお尋ねします。中島さんは、調子が乗ったときに
は朝4時からでも作業に入ると書かれていました。そうすると当然睡眠時間が削
られたり一日のリズムに波が出ると思われますが、どのように調整されているの
でしょうか。
また、エンジニアとして健康の維持に関して気をつけるべきことなどありました
ら教えてください。

エンジニアに限らず、仕事をする上でも健康管理はとても大切だと私は考えています。ソフトウェア・エンジニアにとっては集中力が命なので...


node.js モジュール ajmax の公開

東京Node学園祭2012 アドベントカレンダー 14日目の記事です。イベントの告知の意味も含めて、毎日だれかが1つづつ node.js についてブログで書く、という企画だそうです。

そこで本題ですが、github に ajmax という node.js モジュールを公開しました。npm にも登録してあるので、"npm install ajmax" でインストールが可能です。


詳しくは readme ファイルに書いてありますが、英語なので簡単に解説すると、AJAX(eye candy 的な AJAX ではなくて、実際に非同期にデータをサーバーから取得してページの一部をアップデートするタイプの AJAX) を活用した one-page web application を作るための micro MVC framework です。 

これまでいくつか AJAX を駆使したアプリを作って来ましたが、

  1. ユーザーイベント(主にクリック)にキャッチし
  2. サーバーと非同期通信をし
  3. 取得した JSON データと HTML テンプレートを結合し
  4. JQuery selector で指定した場所にその HTML を置き
  5. さらにそこで生成されたエレメントのいくつかにユーザーイベントを紐付ける

という似たようなパターンのコードを何度もぐだぐだと書かなければいけないのがどうにも気に入りませんでした。そこで、必要なパラーメータだけ JSON で記述してしまえば、メンテナンスもしやすいだろうと、作ったのが、ajmax でも使われている DBI (Data-Binding Instructions) です。

例えば、Facebook の Graph API から取得した友達リストをテンプレートで表示した上で、友達がクリックされたときに、'friend_selected' というイベントを発行するには、以下のように書きます。

FB.api('/me/friends', function(result) {
  ctx.exec([
    { cmd:'html', params:{ template:'friends', selector:'#contents' }}, 
    { cmd:'html', params:{ data:result.data, template:'friend', selector:'#friends', 
      bindings:[
        { selector:'.friend', on:'click', actions:[ 
          { cmd:'emit', params: { event:'friend_selected', target:'client' } } 
        ]}
      ]}
    }
  ]);
});

ちなみに、DBI は JSON なので、サーバー側で記述してクライアントに送ることも出来るし(code-on-demand です)、イベントをクライアントからサーバーへ、もしくは、逆にサーバーからクライアントに送ることも(ただし HTTP を使っている限りは、HTTP のレスポンス時にイベントを発行します)可能です。

サンプルとして、全く同じ動作をするアプリを、片方は DBI をクライアント側で記述し(example_c)、もう片方は DBI をサーバー側で記述する(example_s)、という二通りの方法で書いてみました。

ちなみに、ajmax モジュールそのものは、他のモジュールに依存していませんが、サンプルアプリは node-satatic に依存しています。

モジュールは、サーバー側で使う ajmax.js と クライアント側で使う ajmaxc.js の二つで構成されていますが、DBI をすべてクライアント側で書く場合にはサーバー側のモジュールは必要ありません(つまり、ajmaxc.js は、node.js 以外のサーバーで作るアプリにも応用できます)。 


今週の週刊 Life is Beautiful:10月23日号

今週のメルマガ「週刊 Life is Beautiful」の配信準備が整ったので、内容を簡単に紹介する。

今週のざっくばらん

node.jsとXMPPとreal-time webと

ブログで「node.js と thread hog の話」と題したエントリーを三つほど書きましたが、理由は node.js での本格的な開発がそろそろ必要な状況になって来たこともあり、頭の中を整理しておく必要があると考えたからです。neu.Chat の開発で XMPP を使い始めて以来、モバイルアプリに向けの、いわゆる「real-time web」 を実現するアーキテクチャとして、果たして XMPP が相応しいのかどうかの疑問が湧いて...

オンラインエデュケーションと大学の寡占化

先週は neu.Tutor の学校関係者へのプロモーションのために共同開発者の羽根さんと Boston に行きました。ハイライトは、月曜日のHarvard 大学の教授・教師陣に向けた講演でしたが、Harvard と MIT が進めている「edx プロジェクト」に関しても詳しい話を聞け、とても勉強になりました。edx は単なる「インターネットを活用した教育のオンライン化」などではなく、「世界中の10億人に向けた教育を提供する Harvard 大学」という野望に裏打ちされた、ある意味で大学の寡占化計画であり、20年後には「ぬるま湯」のような日本の大学がすべて経営破綻に陥る、という可能性...

ソフトバンク

ソフトバンクによるSprintの買収の方法(deal structure)が正式に発表されました。日本ではあまり報じられていませんが、deal structure が特殊で、そこにソフトバンク、Sprint 双方の思惑が見えるので少し解説します。この deal は、トータルではソフトバンクが $20 billion でSprintの株の70%を取得する、というものですが、実際には3段階で行われます...

私の目に止まった記事

THE STATE OF THE INTERNET

Internet の現状を、とても良くまとめてある資料なので、ぜひとも見ておくことをおすすめします。「新聞の広告ビジネスが崩壊しつつある」「スマートフォンの売り上げが、パソコンの売り上げを超えた」「Facebookの将来はモバイル広告ビジネスの成功にかかっている」などの個々の事象は、個別の記事を読むことによって漠然と頭には入って来ますが、こんな包括的な形で...

A Turn of the Page for Newsweek

Newsweek が紙媒体の発行を今年の末に終了し、デジタル配信のみに特化したビジネスモデルへとシフトすることを発表しました。Newsweek と言えば、Times Magazine と並ぶビジネスマン向けの雑誌の代表格...

 Microsoft’s Profit Falls as Sales of Personal Computers Shrink

Microsoft が第3四半期(文章中には "its fiscal first quarter"。会計年度は7月から始まります)の決算を発表しました。四半期の利益は去年の同じ時期と比べて22%減の $4.47 billion (約3500億円) 、売り上げは去年の同じ時期と比べて8%減の $17.37 billion (約1兆3000億円)という結果です...

 Microsoft's Surface pricing could be 'a fatal mistake,' says analyst

Microsoft が iPad に対抗して直接販売することになった Microsoft Surface ですが、カバーなしのベースモデルが $499、キーボードカバー付きで $599 という値段設定では、Apple/Google/Amazon とは戦えない、という意見が多く聞かれます。私もベースモデルの価格が $299 に設定されるのではと期待していました...

iPad Mini Event: What to Expect Next Week

米国のメディアは完全に iPad mini が23日のイベントで発表されると決めつけている状態です。iPhone5 の時もそうでしたが、Steve Jobs がまだ生きていたら、担当者のクビが飛びかねない状況です。Jobs がいなくなってから、Appleという会社が最も変わった部分は、実はこの手の新製品の情報のコントロールが出来なくなっている点ではないかと...

UIEvolution 起業ものがたり(4):Steve Ballmer との exit interview

Microsoft を退社することは、99年の末までに決まっていましたが、実際に辞めることを宣言したのは1月の第二週に入った時でした。ちょうどプロジェクトの切れ目でもあったので、仕事の引き継ぎを二週間でして、第三週の終わりには正式に退社し、1月の残りをのんびりと過ごし、2月から始動する Ignition Partners に参加する、という計画でした...

読者からのご質問・ご意見コーナー

今週の質問です。

現在、日本の理系の大学の二年生です。米国の大学への留学は魅力的ですが、先日のNHK特集でもやっていたように、留学すると日本に戻って来た時に就職に不利になる可能性があるのかと思うと、どうしても二の足を踏んでしまいます。このあたりはどう思われますか?

私ならば迷わず留学すると思います。私から見ると、留学すると就職が不利になるような企業のほとんどは、内需指向の一部上場企業で、そこでの仕事はこれまで築いて来た国内でのビジネスを維持するという「守りの仕事」になると思います。一見すると安定した仕事のように思えますが、そんな企業に限って平均年齢が高く...


非同期APIと例外処理(node.js の domain について)

node.js のような非同期APIを使ったプログラミングに拒絶反応を示すエンジニアが多い理由の一つが、非同期APIと例外処理の相性の悪さだ。

Javascript の場合、例外処理はこんな感じに記述する。

function f(i) {
try {
throw new Error('an error #'+ i);
} catch(e) {
console.log('Error caught:', e.message);
}
}

ところが、これに非同期APIが絡むと、とたんに分かりにくくなる。例えば下の例。

function f(i) {
try {
setTimeout(function() {
throw new Error('an error #'+ i);
}, 1000);
} catch(e) {
console.log('Error caught:', e.message);
}
}

setTimeout に渡された無名関数は try ブロックから抜けた後に非同期に実行されるため、例外をキャッチできないのだ。

確かにこれは、直感的なプログラミングとは言えず、こんな部分が拒絶反応を引き起こす人が多いのも納得できる。

ちゃんと例外処理をするためには、

function f(i) {
setTimeout(function() {
try {
throw new Error('an error #'+ i);
} catch(e) {
errorHandler(e);
}
}, 1000);

function errorHandler(e) {
console.log('Error caught:', e.message);
};
}

のように例外を発生する可能性のある部分を個別に try ブロックで囲み、例外をキャッチしたことをイベントハンドラーやイベントエミッター(もしくは、コールバック関数のパラメータ)を通して上位のモジュールに明示的に知らせる必要がある。

しかし、このやり方は、手間がかかるし(すなわち、ケアレスミスによるバグを発生しやすい)、サードパーティのライブラリを使う場合などには応用できない。

この欠点を補うために、node.js に v0.8 から導入されたのが、domain である。domain は非同期に実行されるコールバック関数を一つのコンテキストにまとめて、例外処理をする仕組みで、以下のように使う。

function f(i) {
var d = require('domain').create();
d.run(function() {
setTimeout(function() {
throw new Error('an error #'+ i);
}, 1000);
});
d.on('error', function(e) {
console.log('Error caught:', e.message);
});
}

非同期に呼び出された関数内で発生した例外を try ブロックでキャッチできないという JavaScript の欠点を補うために導入された、「非同期版 try ブロック」のようなものだと考えておけば良いだろう。

domain は現時点(v0.8.12)ではまだ "Experimental" な機能なので、今後 API が変更される可能性も十分にあるので注意が必要だ。

ちなみに、domain の実装が正しくされているかどうか確かめる、簡単なストレステストを書いてみたので下に貼付けておく。

for (var i=0; i<10; i++) {
(function(i) {
setTimeout(function() { f(i) }, 100);
})(i);
}

function f(i) {
var d = require('domain').create();
d.run(function() {
setTimeout(function() {
throw new Error('an error #'+ i);
}, Math.random() * 1000);
});
d.on('error', function(e) {
console.log('Error caught:', e.message, ' in context ', i);
});
}

 


node.js で「サラリーマンの朝」をプログラムしてみる

先日の「node.js と thread hog の話」には、たくさんのコメントをいただいたが、やはり「イベント駆動型」のプログラミングには抵抗がある人も多いようだ。そこで、JavaScript の無名関数を使ったイベント駆動型のプログラミングの可読性が悪くないことを示すために、「朝7時に目覚まし時計をかけて眠りにつき、朝ご飯を食べ終わったら会社に行く」という典型的な「サラリーマンの朝」をイベント駆動型のJavaScriptで記述してみた。

注目して欲しいのは、素早く出来る「着替える」「顔を洗う」などの動作は割り込み不可な動作なので、通常のプログラミングと同じようにシーケンシャルに実行するが、時間のかかる「朝ご飯を食べる」「駅まで歩く」などの動作は割り込み可能な状態で実行し、"complete" のイベントを受けてから次の動作に移る点だ。 

ちなみに、目覚まし時計は 「スヌーズボタン」付きなので、はっきりと目が覚める前にはそちらを押しておき、万が一再び眠りについてしまった場合には、目覚まし時計が5分後にもう一度鳴る、という部分までサクッと記述できてしまうところがイベント駆動型の素晴らしさだと思うのだがいかがだろう。

// 夜寝る前にすること
clock.setAlarm('7:00am'); // 目覚ましを朝7時にセットする
me.sleep(); // 眠る

// 目覚ましが鳴ったらすること
clock.on('alarm', function() {
clock.snooze(); // スヌーズボタンを押す(5分後にまた鳴る)
me.wakeup(); // 起きる努力をする(失敗する可能性あり)
});

// ちゃんと起きることができたらすること
me.on('wokeup', function() {
clock.stopAlarm(); // 目覚ましを止める
me.switchDress('working-style'); // 着替える(割り込み不可)
me.washFace(); // 顔を洗う(割り込み不可)
// テレビを付ける
tv.swith('on').on('interesting news', function(topic) {
web.surf(topic); // 面白いニュースがあったら、ネットで調べる
});
// 朝ご飯を食べる(割り込み可能)
me.eat('breakfast').on('complete', function() {
// トイレに行く(ある程度、割り込み可能)
me.poop().on('complete', function() {
tv.switch('off'); // テレビはちゃんと消しておく
// 駅まで歩く
  me.walkTo('station').on('arrived', function() {
// 電車に乗る
me.rideTrainTo('station near the office').on('arrived', function() {
// 会社まで歩く
me.walkTo('office').on('arrived', function() {
// 働き始める
...
});
});
});
});
});

node.js と thread hog の話(3)

[前回までの話へのリンク]
node.js と thread hog の話(1)
node.js と thread hog の話(2)

では、なぜ今頃になって HTTP Server の c10k 問題(もしくは、thread hog 問題)が顕在化したのだろう。

当時(90年代の終わり頃)と比べて、もっとも大きく変わったのはCPUの性能である。クロック数は、数百MHzから数GHzへと一桁増えたし、マルチコア化もしている。CPU 性能だけ見れば、当時の数十倍の能力が出てしかるべきである。

しかし、実際の人生はそう簡単ではない。サーバーのパフォーマンスはCPU性能だけが決めるわけではないからだ。そこで、ボトルネックの一つとして注目されはじめたのが、thread の数なのである。

前回述べた様に、thread 一つあたり 2MB~8MB のスタック領域を仮想メモリ空間に確保しなければならないので、thread の数が500とか1000を超えたあたりで 32-bit CPU/OS の限界を超えてしまう。64-bit CPU/OS ならばその問題は回避できるが、だからと言ってやたらと仮想空間にメモリを確保し続けるのは無駄だし、thread 切り替えのオーバーヘッドは64-bit CPU/OSになったところで消えない。

特に最近のCPUは、メインメモリーのスループットをはるかに超える速度(100倍以上)で動いているため、CPUコア上に積んだキャッシュのヒット率がとても重要なのだが、あいにくなことに、CPU 上のキャッシュとthreadを大量に使う thread hog 型アーキテクチャとは相性が悪い。それぞれの thread のスタック領域は、当然だが別々の物理メモリーに割り当てられるため、thread の数が増えてくると、キャッシュのヒット率が極端に下がるのだ。

その結果、multi-thread 型の HTTP Server は、同時接続数がある程度を超した時点で、thread 切り替えのオーバーヘッドにより処理速度が落ち、処理速度が落ちた分だけ同時接続数が増えて(server がもたもたしている間に次のリクエストが来るため)さらに処理速度が落ちるという悪循環に陥る、という欠点を持っているのだ。

ここで注目すべきなのは、なぜそれぞれの thread に数MBのスタック領域を割り当てなければならないか、である。実際に必要なスタック領域はそれよりもはるかに少ないかも知れない。実際にスタックに積まれるデータも、HTTP Server の場合、どの thread も似たようなデータである。

にもかかわらず数MBのスタック領域を確保しておく必要があるのは、thread が汎用的な多重処理のメカニズムだからである。OSとしては、thread が実際にどのくらいスタック領域が必要なのか、thread に積まれたデータの中で、どれがそれぞれの thread にとってユニークで重要なデータかを知るすべはないのだ。

node.js は、非同期APIを使ってイベント駆動型で多重処理を行うが、もちろんここにもオーバーヘッドは存在する。スタック上に積まれた変数のうちコールバック関数からアクセスされる可能性のあるものをクロージャとしてアクセス可能にしておく必要がある。非同期APIからのイベントを受けた時に、適切なコールバック関数を呼び出す、という処理もする必要がある。ここだけに注目すれば「thread 切り替え」を「イベント駆動」に置き換えただけの話であり、一見、それほどのメリットがある様には思えない。

一番の違いはメモリの使い方にある。

multi-thread 型のサーバーの場合に、仮に2MBのスタック領域を持った500個のthreadが、それぞれ200KBのスタック領域(実メモリ)にアクセスしたとすれば、それだけで1GBの仮想メモリと100MBの実メモリを使うことになる。この実メモリのサイズは Intel の Core i7 プロセッサの L3 キャッシュのサイズ(8MB)よりも十分に大きいため、キャッシュのヒット率は極端に低くなる。

node.js のようなクロージャを活用したsingle-thread 型の場合、スタックの代わりにコンテキストを保持するのはクロージャだが、ここには必要なデータだけが記録されるため、必要なメモリは数100バイト~数KBである(ちなみに、このメモリはスタックにではなく、V8 のヒープ上にアロケートされる)。仮に多めの10KBとおいたとしても、500個の並列処理が行われたとして、トータルで5MBしか使わない。multi-thread 型と比べて、仮想メモリで200分の1、実メモリで20分の1だ。

特に差が出るのは、スタック領域である。single thread であるが故、スタックとしてアクセスする場所は実メモリの特定の領域に限定される。結果として、それらのメモリは、高速にアクセスできる L1/L2 キャッシュに常駐することになるのだ。

 ◇ ◇ ◇

ここで再度認識して欲しいのは、node.js の素晴らしさは「クライアント側で皆が使っているJavaScriptでプログラムが書ける」という部分などにあるのではない、という点だ。node.js がこれほど多くの支持者を得ているのは「本来記述が煩雑になりやすい非同期処理をJavaScriptの無名関数を利用して書きやすく・読みやすくすることにより、イベント駆動型のプログラミングを多くのプログラマーにとって手の届くものにした」点にあるのだ。

前にも説明した通り、イベント駆動型のプログラミングは、直感的にフローを把握しにくいという理由で多くのプログラマーたちに敬遠されて来た。特にクロージャをサポートしていない言語の場合、非同期 API を呼び出すプログラムと、イベントを処理する部分のプログラムが離れたところに記述されてしまうため、プログラムがとても読みにくくなる、という性質があった。

しかし、クロージャが多くの言語でサポートされるようになった今の時代、イベント駆動型のプログラミングを拒否する理由はあまりない、と私は思う。


node.js と thread hog の話(2)

[前回までの話へのリンク]
node.js と thread hog の話(1)

最近になって「c10k 問題」が広く知られるようになったが、実際には、前回書いたように、thread を使いすぎるプログラム(thread hog なプログラム)はスケーラビリティが悪いということは、当時(90年代の終わりごろ)でもすでに「知る人は知る」問題になっていた。

複数のクライアントマシンとの間のソケットを開きっぱなしにしておく、Proxy Server、Chat Server、MMORPG に関わっている人達の間で、ソケット一つに thread を一つ割り当てるスタイルのプログラミングがスケーラビリティに欠けることが知られるようになったのもこのころである。

当時、Microsoft で MSN Messenger を作っている知り合いが「ついに1万人が同時接続しても大丈夫なアーキテクチャに到達した」と自慢しているので、詳しく聞いてみると、単に非同期な API である WinSock を使って single thread 化しただけだったと聞いて驚いたことを良く覚えている。それぐらい非同期 API を使いこなすことはまれだったのである。

thread はそもそも、process を使った並列処理よりも軽く並列処理をさせるために発明されたものだ。データベースやファイルシステムに頻繁にアクセスする必要があるプログラムの場合、すべてをシーケンシャルに実行するとディスクにアクセスしている時間CPUがアイドル状態になってしまうので、複数の thread にタスクを分散することにより、CPU をより有効に使おう、という発想である。

同じ process に属する thread たちはメモリー空間を共有しているため、データのやりとりはメモリを使って高速にできるし、仮想メモリー空間も1process 分(32-bit CPU の場合システム領域も含めて 4GB)で十分である。thread ごとに必要なのは、thread 切り替え時にレジスタを退避させておくメモリ(数十バイト)とスタック(OS の設定にもよるが 2MB〜8MB 程度)のみであり、process を複数走らせるよりは大幅に軽い。

数 MB のメモリなどは、仮想メモリー空間全体と比べれば遥かに小さく、thread を数個〜数十個走らせたところで、そのオーバーヘッドはたかが知れている、と考えられていたのだ。

proxy server や chat server の場合も、「開いたソケットから送られて来るデータを待つ」という処理を先の「ファイルにアクセスする」「データベースにアクセスする」と同じく「CPUがアイドル状態になってしまう時間がかかる処理」と見なせば、同じ様に複数の thread を使うことにより多重化する、というのは当然の発想である。初期の proxy server や chat server がそんなアーキテクチャで作られていたのもそれが理由だ。

しかし、実際にそんな server をネット上で運営すると、すぐに壁に突き当たる。たとえ thread 一つあたりに必要な仮想メモリのサイズが 2MB であっても、そんなサーバーに1000人が同時に接続すれば、2GB が必要となり、32-bit OS が1プロセスあたりに割り当てることのできる仮想メモリのサイズを超えてしまう。

そこで使われる様になったのが、非同期 Socket API を使った多重化というテクニックである。メインの thread 一つだけを走らせ、それがイベントループで、開いた socket からのイベントを順に処理して行く、というアーキテクチャである。

ただし、このアーキテクチャを採用した場合、イベント処理中にディスクやデータベースにアクセスすると、そこでCPUがアイドル状態に入ってしまうため、その手の時間がかかる処理すべてに非同期APIを使い、イベントループで、ファイルシステムやデータベースからのイベントを受けてイベントハンドラーに渡す形にしなければならない。データベースへのアクセスが同期型のものしかないシステムには適さないアーキテクチャだ。

当時、proxy server や chat server が非同期APIを使った single-thread なアーキテクチャに移行したにも関わらず http server がそちらに移行せずに mutli-thread なアーキテクチャのままでいたのにはいくつかの理由がある。

前回書いた様に、多くのプログラマーが非同期APIをアレルギーのように嫌っていたのも理由の一つである。特に、当時は非同期プログラムを連続的に書くことを許すクロージャが普及していなかったこともあり、非同期プログラミングはとても不便であった。私が IIS に対抗して作った single-thread アーキテクチャの micro-server も、非同期 API を呼び出す前には、イベントハンドラーに渡すべき情報(コンテキスト)を明示的に一所に集めて渡す必要があり、かつ、結果を処理するイベントハンドラーは呼び出し側とは別の場所に書いてある、という煩雑なプログラミングが必要であった。

もう一つの理由は、http server の場合、prozy server や chat server と違って、get や post を処理する間だけ thread を走らせれば良いため、例え同時に1000人の人がウェブページを閲覧していたとしても、実際の同時アクセス数はそれよりも遥かに少ない、という特徴があったからである。

また、当時はそれぞれの CPU の能力も、今のサーバー用の CPU と比べると2桁ぐらい性能が劣っていたため、thread の作り過ぎによる問題が出る前に、他の部分がボトルネックとなって、(ユーザーの増加に応じて)サーバーの台数を増やさざるを得ない状況になっていた、という面もあったのだと私は解釈している。

つづく


node.js と thread hog の話(1)

ここ数日、 node.js で色々と作りはじめているのだが(node.js が一番力を発揮するのは、xmpp server や、push notification server のようにソケットを開きっぱなしにして非同期通信をするケースだと思うのだが、それについては来週のメルマガで詳しく解説する)、これで思い出すのが Microsoft 時代の「"thread hog" 退治」だ。

"thread hog" とは私が作った造語で、"memory hog" (メモリをやたらと使うプログラムのこと)と同じように、thread を不必要に作るプログラムのこと。

最初に出会った thread hog は、Microsoft が作っていた proxy server だった。コネクションが1000を超すとやたらと遅くなり、しまいには落ちてしまうという欠点を持っていたため、一時は「出荷出来ないところか、社内でも使えない」と大問題になっていた。たまたま担当者が知り合いだったので、理由を尋ねると、コネクション1つあたり1つの thread を使っており、これが問題だと言う。

私はそのころちょうど、single thread の web server を作って (multi thread 派の)IIS グループとwebサーバーのあるべきアーキテクチャについて論争を繰り広げていたので、「これは良い機会」だと、担当者に非同期ソケットを使って single thread 化することを強くすすめた。彼も最初は懐疑的だったが、実際に試してみると驚く様にスループットがあがり、数千のコネクションを楽々とこなせる様になった。

次に出会った thread hog は、OLE (Object Linking and Embedding)だ。Windows 95 上で Excel の表の一部を Excel から Word に copy & paste するのにやたらと時間がかかるので、デバッグして欲しいとの要請が来たのだ。

調べてみると、OLE の中にある DCOM (Distributed COM)が、プロセス間通信のたびに thread を生成し、かつブロックしている。Excel から Word に copy & paste をすると Excel と Word がお互いの method を何重にも呼び合うため、たかが copy & paste のために thread が10個以上作られていたのだ。これも proxy server のケースと同じように DCOM のプロセス間通信の部分を大幅に書き直して、thread をブロックせずにすべて非同期 API で処理する様にして、大幅なスピードアップをはかることに成功した。

Exchange Server へのリモートアクセスを可能にする MAPI に関しても全く同じ問題を発見したが、これに関しては、Exchange グループは、私の進める MAPI の非同期化に猛反対をし、ローカルにデータベースの cache を作る、という方法で逃げた。Microsoft の MAPI が、インターネット・スタンダードである POP3 や IMAP に決して勝てなかった理由はここにあるのだが、当時の Exchange Server の連中は非同期APIをアレルギーのように嫌っていたので、どうしても無理だったようだ。

この経験を生かして、Web Server も single thread 化するというバトルを IIS グループに挑んだのだが、ここでも同じような激しい抵抗に会ってしまう。Web Server を single thread 化するということは、HTTP transaction の処理中のファイルシステムやデータベースへのアクセスも非同期APIを使わなければならないことを意味するが、「そんな面倒なことは開発者はしたがらない」というのが彼らの言い分だった。

そんな私から見ると、node.js のアーキテクチャはものすごく納得できるのだが、同時に「全てが非同期でなければいけない」という部分にアレルギー症状を示すプログラマーがいる理由も良くわかる。

しかし、CPU が1インストラクションを実行する時間と、ネットワーク通信をする時間(もしくはディスク上にあるファイルにアクセスする時間)は開く一方なのだから、この違いをプログラマーに見えないようにしよう、という発想自体が根本的に間違っていると私は思う。

つづく


今週の週刊 Life is Beautiful:10月16日号

今週のメルマガ「週刊 Life is Beautiful」の配信準備が整ったので、内容を簡単に紹介する。

今週のざっくばらん

neu.Chat とXMPP/Jingle

前回のメルマガでは、neu.Chat を XMPP 経由で動かすことに成功したところまで報告しました。XMPP とは、ひと言で言うと「サーバーを経由して二つのデバイス間でリアルタイムにメッセージを交換する仕組み」です。Instant Messenger はこの仕組みを利用してユーザーが入力した文章を XMPP 上のメッセージとして交換することにより実装されています。neu.Chat の場合も基本的には同じで、ユーザーが入力した文章の代わりに、ユーザーが指を使って...

ソフトバンク

ソフトバンクのイーアクセスの買収に関しては、イーアクセスが持っているLTE バンド(LTE 通信用に政府から割当らあえた周波数帯域)と、iPhone がサポートしている LTEバンドを見ると納得できます。LTE は CDMAやGSM と同じく携帯電話用の通信プロトコルの一つです。LTE を最初に提案したのは NTT ドコモですが...

私の目に止まった記事

US Consumers Need Softbank To Buy Sprint

ソフトバンクが Sprint/Nextel との買収交渉に入った件は、米国でも大きく取り上げられています。この Forbes の記事もその中の一つですが、ソフトバンクという企業が海外のメディアからどう見られているかが良く分かる記事なので、ぜひとも読んでみてください。ここにも書かれている様に、米国では...

Apple Hits New High with 13.6% Share of U.S. PC Shipments in 3Q 2012, Lenovo Captures Worldwide Title

Gartner が発表した、2012年第三四半期のパソコンの米国におけるマーケットシェアに関する記事です。去年と比べて業界全体が13パーセント落ち込む中、シェアを伸ばしたのが Apple と Lenovo です。一方、日本メーカーで唯一ランク入りした東芝は、ここ1年間でマーケットシェアを...

iPhone adoption among teens hits 40% in U.S., iPad at 31%

上の記事とも関係しますが、米国のティーンエージャーにアンケート調査をしたところ、40%が既に iPhone を持っており、次の買い替えのタイミングで iPhone にする予定のティーンエージャーにいたっては62%にもなる、という記事です。実際の販売台数に関して言えば、Android 端末の方が iPhone を上回っているにも関わらず...

Advertising Becomes Amazon's Newest Low-Price Weapon

Amazon が最近力を入れはじめた「広告」の話です。Amazon と広告というとあまりピンと来ませんが、実は私は、Amazonこそが「インターネット広告ビジネス」のあるべき姿を具現化するのに一番近い位置に立っていると思っています。インターネットの広告業界の一番の悩みは、バナー広告のように、いかにも広告らしい広告は全く見てももらえなく...

Shareholder Letter (by Steve Ballmer)

Steve Ballmer が株主に向けてannual reportの一部としてMicrosoftの企業戦略を説明した文章です。最近は、この手の文章がオンラインで読めるようになったので、興味のある会社の annual report には目を通しておくと良いと思います。特に今回のものは、Microsoft の今後の10年を占う意味で重要な転機を示していると思うので、少し解説します。Microsoft の株価は、2000年の...

UIEvolution 起業ものがたり(4):Microsoft からの退職

Brad たちが立ち上げるベンチャー投資会社 Ignition Partners にパートナーとして参加できるとなったので、Microsoft を退職することには何の未練もなくなりました。1999年の12月のことです。すぐに辞めても良かったのですが、これまでボーナスとしてもらってきたストックオプションのうち、exercise する権利(株に交換する権利)が生じていないものがまだ...

読者からのご質問・ご意見コーナー

今週の質問です。

今回は、気になった記事について感想を述べさせていただきます。気になった記事は以下になります。

----------------------------------------
日本はどうして原発を止められないのか
第三章 原子力依存症という病(3)
----------------------------------------

この記事の冒頭で「カリスマ的なリーダーシップを嫌い、合議制でしかものごとを決められない日本」とありますが、これを前提とした国の問題を書かれると、解決の道筋が見えず
絶望的な気持ちになります。
シャープの問題なら、多少影響はありますが、他人事のように潰れればいいじゃんと考えてしまいますが、国の政策、特に放射能関連の場合は、さすがに他人事とは思えません。

また前に(去年と今年)NHKスペシャルで放送していた、なぜ日本はアメリカと開戦したか、戦争を早期に終結できなかったかという放送でも日本のリーダの決断力の無さについてまとめられていました。(特にアメリカと開戦した回の'日本に独裁的な指導者がいなかったために
開戦回避を決断することができなかった'というナレーションが印象的でした。)

政治の問題解決における決断力の無さは、戦前からの問題と感じます。

もはや「カリスマ的なリーダーシップを嫌い、合議制でしかものごとを決められない日本」は、
日本の文化なのかなとも思います。ただロンドンオリンピックのバトミントンの無気力試合を、
制度上の問題とおっしゃってましたが、日本の政治のリーダーシップの無さも、制度的な問題とも感じます。

中島さんは、この政治のリーダーシップの無さについてはどのようにお考えでしょうか?
今後の、メルマガで記載していただけると幸いです。

とても良い質問だと思います。確かにすべてを「突出したリーダーシップを嫌う文化」に帰着させてしまうと、出口が見えなくなってしまいます。歴史的に見れば、織田信長や徳川家康は立派なリーダーだったし...


日本の発展を阻む「逃げ切りメンタリティ」

去年の福島第一での原発事故後、日本という国の統治機構のさまざまな問題点が露呈されることとなった。国会事故調が指摘した様に、事故の根本の原因は「電力会社と規制機関の癒着」にある。ここを徹底的に検証し、修正しない限り原発の再稼働などありえないのだが、そんな「まっとうなプロセス」をとることが出来ない点がこの国の一番の問題である。

国民の意思を反映したはずの「原発ゼロ政策」がいつのまにか骨抜きにされる、最も大切だったはずの原子力規制庁の「ノーリターン・ルール」がないがしろにされて原子力規制庁が実質的に経産省の傘下に入る、国会事故調があれほど第三者委員会と国会によるオープンな人事決定プロセスの必要性を訴えていたにも関わらず原子力規制委員会の人事が密室で決まる。これがこの国の体質だ。

結局のところ、この国の方向性を決めているのは、国民でも政治家でもなく、霞ヶ関のエリートたちと彼らと強く結びついた産業界の一部だということが良く分かる。代表的なのが、鉄鋼業・セメント・非鉄金属・造船・化学工業などの重厚長大産業、土木建築業、そして電力会社を含むエネルギー産業だ。

バブルの崩壊までの高度成長期はそれでも良かった。エネルギーを大量に消費する重厚長大産業、インフラを作る土木建築業、そしてそこに必要なエネルギーを提供するエネルギー産業が、日本のGNPを押上げ、雇用を確保してきたからだ。

しかし、今やそんな「エネルギー大量消費」型のビジネスは中国やインドにシフトしており、日本という国はこれまでとは違う新しい戦い方を見つけなければならない転機に来ているのだ。

ドイツにできた脱原発・エネルギー大量消費に頼らない経済発展は、日本にもできてしかるべきである。問題は、急激な変化を望まない企業と、彼らと強く結びついた霞ヶ関が痛みを伴う改革を嫌い、問題を先送りし続けている点にある。急激な変化は、主役の交代を意味する。変化の隙をついてソフトバンクやライブドアのような新参者が次の時代の主役になってしまうことは、なんとしてでも阻止ししたいのだ。

つまり、高度成長期の成功により日本という社会の中核を担う様になった重厚長大な大企業が、短期的な保身のために抵抗勢力となって日本の発展を阻んでいるという皮肉な結果になっているのだ。典型的な「逃げ切りメンタリティ」である。

そんなことを考えていたら、数多いジャーナリストの中でも私が最も信頼している神保哲生氏がまさにこの点をとても分かりやすく解説していたので、ぜひとも見ていただきたい。