RubyConf2008 2日目

今日は最後に Dave Thomas からの Keynote がありますが、午前中にはとくに全体会はないので昨日よりは遅い立ちあがりです。ひとまず、日本の仕事もしつつ、いろいろチェック。

そういえば、昨日 irc でレオさんの言ってた「日本の Rubyist と仲良くなろうの会」の企画はどうなったんだろう?

今日もまたフロリダらしい日射しのなか朝御飯。直射日光にさらされてると、この時期なのにけっこう日焼けしそうです...。

昨日の分散の話が、分散処理方式の種類みたいなものに焦点をあってるとするなら、今日のは分散環境化での協調動作の一般論みたいなとこですね。

cron で実行するような繰り返しタスクをどのマシンにおくか... Single Point of Failure (SPoF) になってしまうのは嫌ですね。そこで、複数マシンで信頼性を高めることを目指します。
よくやるのは複数 mongrel プロセスですが、問題があります。

    • asynchrony (プロセス間の同期をどうするか)
    • locality (局所性)
    • failure (異常系)
    • byzantine (セキュリティのこと?)

どうやって相手の存在を知ったらよいのか? Truely anonymous には対応できないが、プロセスの数などがあらかじめわかっていれば解決できそう。というわけで、グループが把握できたとします。

次の問題は「同意」。どうやってリーダーを選ぶのか。乱数を利用したりして、リーダーを選ぶ。「同意」には時間がかかるので、パフォーマンスと信頼性のトレードオフ

でも予期しにくく、テストもできない、そんなひどい状況があります。そのときどうするのか? 完全に信頼できるコードとまずいコードの間の現実的な解。よく使うのは memcached?


SPoF をつくらずに、これらを解決できる自作ライブラリをつくってみましたってことらしい。


いくつかのリアルな問題の解決策を実演。

    • TokenWorker

リーダーの選び方。memcached::add API を使って、最初にはいってきたプロセスがリーダー。
デモはよく見えず... (文字の色とサイズが微妙すぎる)

    • StaticQueueWorker

リーダーがキューをもち、他のワーカーに振り分ける。たぶんリーダーが落ちたら、残りから選ぶっぽい。
# やっぱりデモ見えない...


ここで、Paxos ("poxos made live" でぐぐれ) の話。

Paxos algorithm - Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/Paxos_algorithm

分散アルゴリズムのひとつで、Google がたくさんの人と金をかけて実装しようとしてきたとか?
2フェーズコミットに似たようなものか...。異常系のリカバリが大変。

politics でも paxos の実装を試みたが、あきらめた。将来もっかい試してみたいそう。



毎年の名物になりつつあるタルボット。初回の RubyConf 以来 8回目だと思います。Ruby の話しないのに会場はきっちり埋まってました(笑)。

全員たたせて、RubyConf参加回数の少ない順に座らせていって...最後に残ったのは、ポールブレナン。高橋さんは残念ながら隣の部屋でした。

で、とうとうと話はじめます。今年はスライドもないみたい... orz
レオさん++。 <(_ _)>



ソフトウェアは art であり、人の営みだからこそ、感情と向きあわねばならない。
恐怖という感情について考えてみよう。


「なにもない」という怖さ
既存のコードの怖さ
美しいコードをこわしてしまう怖さ
はずかしいものをつくってしまう怖さ
時間がかかりすぎてプロジェクトを完成できない怖さ

はじまることの怖さ、完成することの怖さ
...


「怖さ」をインタビューして部屋中をかけまわるタルボット。このあたりの一体感のつくりかたはほんとうまいなと思う。

怖さはワーニングシステムであり、判断材料にはならない。してはいけない。そこだけは注意しよう。
冷静に判断して、決めなければいけない。


怖さを解消するには学習とテスト。
未知のものへの恐怖は本性だが、自覚があるのとないのでは違う。
テストで問題を分割してけば小さくできれば怖くなくなる。
プロトタイプをつくってみるのがいい。最初から捨てるつもり。


最悪の場合を想定しよう。

"The War of Art" って本がお薦めらしい。"The Fear of Art" も。

なにかを創造するときのヒントが書かれている。ここで再び会場にヒントを求めてタルボットが部屋中をかけまわりました。

これもおすすめ。


怖さを乗り越えるもっといい方法は、愛、情熱。
好きなことをやっていれば、怖さがあってもだいじょうぶ。そもそも情熱がなければ、怖さに耐える理由もない。


# irc から抜粋。

01:13 shyouhei_: 毎年思うんだけどRubyistは最低でも一生に一度以上はRubyConfを経験しておくべき。
01:14 kakutani: RubyKaigiに呼んでもこうはいかないだろうなあ、と思う。タルボっちゃんの話は。
01:14 takahashim: まあ、そうかも>talbott
01:16 takahashim: RubyConfは人生を変えるよなあ

なんかふつうに関数型プログラミングの紹介でおわってしまいました。

関数型プログラミングのポイントは状態を持たないこと、関数が一級市民。状態が不変であれば、同期の必要なく並列化できる。でも、一般的に関数型プログラミングの欠点はオブジェクトをたくさん作りすぎること。

Ruby における不変性は? attr_reader なら read only、副作用のない関数の紹介。Ruby における一級市民の関数は、メソッドではなくブロック。メソッドは微妙に違います。

関数型プログラミングでありがちなのが再帰ということで、ここでフィボナッチ数列の例。ほか重要な関数として、map, filter, fold/reduce などを紹介。(Ruby だと、map、select、inject?)

あとは、関数型プログライングは宣言的という話から、ActiveRecordDSL もまさに宣言的だよね、とか...だんだん雲行きがあやしい。


そして突然、Actor model of concurrency

関数型プログラミングのパターンマッチングは OO のポリモーフィズムと似ているとか...

で、最後にまとめです。
不変がいい、副作用のない関数がいい、...

    • what functions go inside a type vs outside
    • watch for overhead for copies and recursion
    • mix pattern matching and polymorphism

うーん。


  • ランチタイム。

メニューは昨日とほぼ同じですね。
それにしても暑い。となりのホールで日焼けマシンの展示会の準備が行われているのもうなずけます。



Jim Weirich のお話です。
これまではムーアの法則の恩恵を受けることができたが、今後クロックスピードが頭打ちに。今年はこの前フリではじまるセッション多いですね。
従来のパフォーマンスは、クロックスピード、最適化、キャッシュがポイントでしたが、今や Mac のハイエンドマシンもたったの 3.2 GHz... (8GHz のマシンを誰かもってないのか?って聞いてましたww)
で、これからのパフォーマンスは、HyperThreding、マルチコア、キャッシュがポイントとのこと。

(参考)

    • Herb Sutter
    • Charles Miller
    • Java Concurrency in Practice


でも、マルチスレッドは扱いがむずかしい、Rails がスレッドセーフになるのはうれしいけど、マルチスレッドアプリをつくりたいとは思わない、というわでお馴染みの銀行口座の例を粛々とデモしました。

まずは、10スレッドで、口座に $1ずつ入金するのを 100,000回繰り返し。当然結果がまちまち。race condition。スレッドによる値のコピーと ++ をアトミックにする必要があるということで mutex。mutex を使ってクリティカルセクションを守れば成功。

次は、口座A からは debit して、口座B に credit する例。口座が負にならない条件をどこにつけるかがポイントです。ループごと mutex にいれてしまうとクリティカルセクションがでかすぎるので、while の条件を mutex のなかで再度確認するようにします。

こういうマルチスレッドなプログラムをテストするのは大変です。とっても大変です。

次の例は、5つの口座で順番にお金を transfer していきます。5つのスレッドで実行すると...見事にデッドロック。解決するために、スレッドに優先度をつけてみるとかですかね。

    • 1) protect every shared memory access with a synchronizing lock
    • 2) beware of extended situations that need to be atomic
    • 3) have a strategy in place to avoid a deadlock in the presence of multiple locks
    • 4) evaluate every single library used by your program to see if they also follow rules 1-3

というわけで、使ってるライブラリをちゃんと確認しないといけないということです。大変です。 orz


ここでどう展開するのかなぁと思っていたら、並列プログラミングではデータの共有が問題の元凶ということで、Ruby 以外の言語を紹介。Paul Graham の Blub 言語の話とかも。

no variables, no assignment, no explicit loops
constants only, pattern matching, recusrsion (tail recursion)

Lisp っぽい構文の説明。基本的に状態を変更できないが例外はあるそうです。
Vars - thread local variables (impossible to share)
Refs - STM (shareable, but only in a transaction)


そして、来年本がでるそうです。
The Pragmatic Bookshelf | Programming Clojure


最後に、並列プログラミングは難しいので、従来の手続き型言語だとつらい。Ruby でマルチスレッドプログラミングするのは大変。関数型言語がよいよ、とまとめていました。 (^^;


資料はここらしいです。

優秀なひとが集っても、いいコードになるとはかぎらない..
ひどいコードをどう減らすか? ペアプロ、メンテナを意識、レビュー、...でもやっぱりダメなコードになることもあります。
great code + time = trouble (いいコードも時間をかけるとおかしくなります)


というわけで、メトリクスを活用しましょう。
とはいっても、カバレッジも100%あればいいというわけではないです。(30%はひどいけど)テストもあればいいというものではない。C1、C2のカバレッジがあるなら cool かもね (rcov は C0)

    • zenspider のFlog の話。

Flog のスコアは 10 を中心に正規分布するよう計算されうようです? (0-10, 10-20 あたりをよいと言ってたけど、よくわからないです...)

    • Saikuro の話。

cyclomatic complexity を計測します。これで、複雑なメソッドを把握して、リファクタリング
例にあげていたのは、damerau levenshtein distance examplegoogleの「もしかして」機能っぽい。

複雑なメソッドをリファクタリングすることで、理解しやすいコードになるとともに、潜在的なバグもみつけられます。過去の精神状態もわかりますww
でも、やりすぎはよくないです。単純に Flog のポイントをさげるために inject とか使うとわからなくなりがちです。複雑なコードを残すときには、ちゃんと説明も残しておきましょう。

    • Source Control Churn。

ファイルの修正回数で降順にソートすることで、変更回数の多い(問題のありそうな)ファイルがわかります。とか言ってました。



メトリクスの注意点。数字はうそをつくこともあります。なので、意味のわからないひとにはみせないように。まとめ。メトリクスで対応の優先順位がつけられ、バグや隠れた複雑性を発見できます。

  • Metric Fu

rcov, flog, saikuro, code churn, rails statsを包含してます
http://github.com/jscruggs/metric_fu
http://metric-fu.rubyforge.org/

Fibonacci Software Development。
最初 hustle して、次に refactor して、そのあと Optimizetion、..ということで、だんだん時間軸が長くなり最適化とか大事になってくるよね、という話。

結論としては、以下でしょうか。

    • Ruby のよさをいかそう
    • アーキテクチャはパフォーマンスに大きな影響
      • スループット > パフォーマンス (たぶん TAT=Turn Around Time のこと?)
      • 並列 != スレッド
      • 必要に応じて C拡張の利用


スループットを最大化するのに、CPU を激しく食ってるとこを別メソッドに切りだして、メッセージングキュー経由で非同期化するなんてことをしてました。最近は Starling があちこちででてきますね...うぅ。

RubyForge: Starling: Project Info


Starling is a light-weight persistent queue server that speaks the MemCache protocol. It was built to drive Twitter's backend, and is in production across Twitter's cluster.

http://rubyforge.org/projects/starling/

About This Blog: Beanstalk Messaging Queue | Ruby on Rails for Newbies


Fast, simple, designed to mirror the style of memcached. Rails plugin available, or usable with a simple Ruby-based API. Server written in C, but is very easy to install.

http://nubyonrails.com/articles/about-this-blog-beanstalk-messaging-queue


そんなこんなで、
job queue + 50EC2 instances 使ったら、50,000,000GETs/day トランザクションさばけたよ、とか事例の話も少ししてました。

    • Defer Blocking IO
    • EM-HTTP-Request (EventMachine でリクエストを非同期化)
    • Curl::Multi

Ruby は遅いので、最適化重要。

orz..




なんだかネタ的なセッション。
格闘技とコーディングの共通点から、Code Kata を Dave Thomas や Uncle Bob が提唱。

CodeKata

http://codekata.pragprog.com/


演舞のヒデオ...ながっ。演舞すればフィードバック得られる。
というわけで、これからやってみせるから採点してね、ということで黙々と発表者がコーディング開始www
ぼくらはそれをじっと眺めてます。 (^^;
(よくは見えませんでしたが、IntelliJ IDEA 使ってましたね)


ひまだったので、ぐぐってみたら、こんなものが↓。同じひとですね。

effective software development

At the recent Ágiles2008 conference in Buenos Aires, Micah Martin gave a demo of test-driven development with ruby. You always need some sort of application to write in presentations like this, and it's not always easy to find one that's simple enough to serve the purpose of a demo and yet interesting enough to hold people's attention. Micah based the demo on Langston's Ant, which I think meets both those criteria.

http://dnicolet1.tripod.com/agile/index.blog?start=1225810027

もひとつ、スパーリングについて。
Javaロボコード みたいな感じで、潜水艦ゲームの戦術を競いあわせましょうって話。で、互いに学びあいましょうってことか。

http://sparring.rubyforge.org/battleship



夕飯。Dave Thomasu の Keynote まで時間が多少あるので、みなでホテルの外のレストランへ。はじめて歩いてホテルの外に出ました。しかし、お店が遠いです...。
結局、時間もないのでマックやスーパーで夕飯をテイクアウトして帰途につきました。

戻ってきたら、恒例の書籍の抽選会。

...