2008-02-26


分散プロジェクトの誤謬

タネン本を始めとする分散システムの教科書で必ずとりあげられる話題に "分散コンピューティングの誤謬" がある. 以下 Wikipedia から引用.

ネットワークプログラミングをしたことがあれば, いずれも該当のバグに思いあたる節があると思う. これらはみな複数台の計算機が関わる際の問題であり, いわばコミュニケーションの問題. 同じ問題は計算機同士に限らず, 人と人の間, 組織の間でもおこる. 順番に例を並べてみる.

<伝言や連絡は信頼できる> : できない(よね?) ミーティングには欠席者がいる. 後輩は話を聞いてない. メモもとらない. メールはスパムに埋もれ捨てられる. 伝言は忘れられる. 言葉が届いても聞き間違いはある. 誤解や勘違いもある. 意思疎通は難しいものだ.

<レイテンシはゼロである> : ゼロどころかミリ秒ですらない. 同僚が昼食から戻るまで 30 分ある. メールが読まれるのに数時間はかかる. 返信には更に数時間から数日. 上司は明日まで帰ってこない. 定例ミーティングは来週だ.

<帯域幅は無限である> : まさか. 言いたいことを言葉にするのは大変. メールを書く速度には限界がある. 喋る速度も. 電話越しにホワイトボードは使えない. ウェブカメラの解像度は粗い. 忙しい上司や顧客は話の途中でいなくなる.

<連絡や会話はセキュアである> : 残念ながら. 上司の目をちょろまかす相談を自席ですることはできない. 困った同僚への対処を廊下で願いでることはできない. 見積や予算のマージンを顧客の前で話すことはできない. デートなので早退します, なんてふつうは口にしない. (会社では.)

<担当者(社)は変化せず一定である> : むずかしい. 頼りになる同僚は燃えプロに引き抜かれてしまった. 頼りにならない派遣技術者が燃えプロに投入されてきた. 上司は左遷された. 顧客の窓口は退職してしまった. プロジェクトが中国に移管された. リストラされた.

<権力者(社)は一人である> : 何人いても不思議はない. PM がいて, 元請けの開発者がいて, 顧客の担当者がいて, 顧客の上司がいて, コンサルタントがいて, エンドユーザ(美人)がいる. みんな言うことが違う.

<対話コストはゼロである> : 金を払って済むならまだいい. 上司は顧客の顔色を伺い疲れている. PM はインド人の英語がわからず苦んでいる. 末端プログラマはメールにちりばめられた親受け社内の符号に面喰らう. ジャーゴンを使わずエレベータピッチに挑み筒井康隆の気分になる.

<人員は均質である> : 時代は diversity. 転職してきた同僚は空気を読まない. 共同開発の相手はコーディング規約を守らない. 常駐先の定例ミーティングは 8:30AM から. そこは extract interface して OnXxx() で inject してね, と頼んだらぽかんとしている後輩. 聞いたこともないプロセスのなんとか計画書を埋めろと手渡される.

こんなところかな. 複数台の計算機で協調するのが難しいように, 複数の人間や組織が協調するのも難しい. そしてプログラマが誤った仮定に基いて脆弱なコードを書いてしまうように, プロジェクトが誤った仮定に基いて迷走することはよくある. これを仮に 分散プロジェクトの誤謬 と呼ぶ.

社員 4 人のチームで 12 ヶ月との見積を睨み, 夏の展示会に間に合わないと青ざめる経営陣. そこに "中国にいい開発チームをみつけたんですよ. すぐ 8 人用意できるって!" などと 嬉しそうに走りよる人売りエージェントは, Fred Brooks だけでなく Bill Joy も敵に回している.

Martin Fowler の第一法則

PoEAA の中で, Martin Fowler は 分散オブジェクト設計の第一法則 を 次のように定義している: 分散させるな. 分散プロジェクトについても同じことがいえる.

世間では共同開発やグローバル化を進める流れがあり, 一部にはそれを好む向きさえある. そうした分散プロジェクトを支援, 効率化するためのツールや方法論も盛んに宣伝されている. しかし, それらは分散の困難をいくらか緩和するだけだ. 本質的な難しさは変わらない. CORBA を EJB や WSDL に置き換えたり, HTTP を deflate してみたり, load balancer を置いてみたり. これらがどれも同一アドレス空間の関数呼び出しには遠く及ばないように, 最新の電子会議システムも Enterprise Wiki も 隣の同僚に話しかける相談やホワイトボードの代替にはならない. (地理を隔てたコミュニケーションの問題は, その一部が分散コミュニケーションの誤謬そのものに縛られている点は興味深い.)

分散をする言い訳はいくらでもある. セキュリティ, スケーラビリティ, 性能, 納期, 能力, 規模. しかし, これらの目的と引き換えに失うものをよく考えてほしい. それが本当に割にあうのか. 疑わしい. 分散の困難から目を背けてはいけない. たとえば直列化のコスト. 配置の手間. endian を誤解した buffer overflow. 再送のおこす輻輳と迷走. firewall 設定の交渉. バージョン混在のカオス. どれも分散しなければ起こることはない.

空想の隣人

メタファーばかりで分散プロジェクトの誤謬がピンとこない人のために, 簡単な思考実験がある.

自分と同じフロアにいないプロジェクト関係者の中で, 苦手, 嫌いな人をひとり想像してみるといい. 画面を見るたびに違うことを言う顧客. 電話に出ない親受けの PM. 腹のたつ苦情ばかりよこす北京の開発者. 似たようなバグばかりあげてくる隣のビルの QA. 誰でもいい. (一人くらいはいるでしょ?)

その彼/彼女が, 自分と同じ会社の同僚として, 隣の席で働いている様子を想像してみよう. 自分が相手にネガティブな印象を持った瞬間を思い出し, その状態で同じことが起こるか考えてみる. もし起きそうもないなら, その不愉快な感情は分散プロジェクトの困難が引き起こしたものだ. 腹のたつその場面は, ぶっきらぼうなメール, 上司からの伝聞, 関係者が入り交じる仮面会議の一幕ではなかったか. 私の経験だと, 7-8 割はこのカテゴリにある. ほんとに苦手な時もたまにはあるけど...

これは個人相手に限らない. 自分が仕事の中で感じた不愉快や苛立ちを思い返し, 同じように考えてみるといい. 同僚だったら仲良くできるだろうにと悲しくなる. (どんな相手とも仲良くする技を持つ PM は 10GbE みたいなもんですかね. あれはすごい.)

分散税

トラブルを避けたいならルールは単純だ. 分散させるな. 会社をまたぐな. 部署をまたぐな. フロアをまたぐな. プロジェクト, 特にソフトウェアの開発は密なコミュニケーションを必要としている. 壁を越える努力をする前に, そもそも壁のあるところで仕事をしてはいけない.

これはほとんど自明のことに思える. 実際, 本当に重要なプロジェクトは自社で人を集めて開発をする. あるいは新会社を組織する. 深刻な遅延を抱えるプロジェクトは人をプロジェクト部屋に貼り付ける. (Yordon の デスマーチ も参照.) 抜け目のない顧客は担当者リストの提出を求め, 孫請けのいないことを確認する. こまめにオフィスを見学する. (そして狡猾な PM は孫請け社員に自社の名刺を渡す.)

一方で, こうした注意を払わないプロジェクトも多い. なぜか重要でないプロジェクトほど組織をまたぐ傾向にある. 寄せ集めってやつね. しかし重要でない仕事だからといって効率が悪くていいこともない. 予算の割り振りをみれば, 重要でないプロジェクトの予算(の合計)と 社運博打プロジェクトの予算に大きな差は無かろう. 博打だけだと外れた時に倒産しちゃうし.

ここにも <分散プロジェクトの誤謬> がある.

たとえば, 100 人の開発者を擁する企業 A で, 50 人規模のプロジェクトが 4 つ動いているとしよう. どのプロジェクトも A 社の開発者が 25 人, 協業 B 社が 15 人. おなじく C 社が 10 人いると仮定する. (そこそこありがちでしょ?) A 社は 200 人分の売り上げと 100 人分のマージンを稼ぐことができる. さて第一法則に従い, A 社は自社の headcount で閉じた開発に専念しようと決める. ところが売上は 100 人分に半減してしまう. マージンもなくなる. 分散の罠から逃れて生産性を高めたはずなのに, 稼ぎが減ってしまった. おかしい.

A, B, C の三者が共同で開発をする場合, 境界は A-B, B-C, A-C の三つある. 顧客は 1 プロジェクトあたり 50 人分の人件費と, 3 つの境界のオーバーヘッドを負担している. ところが領収書にそれはあらわれない. 組織の構成にかかわらず, 額面では頭数分の費用をはらうことになる. そして期待した成果があがらずがっかり. プログラマが RPC のエラー処理を忘れるように, このとき顧客の購買部は開発チームの組織構成を見落している. A 社の収益は分散のコストに対する顧客の無関心に依存していたわけ. (もちろん他の要因もある. 一つのパターンは, 売上とソフトウェア品質の相関が弱い場合. うまく手を抜くと利鞘がふえる. プログラマは虚しい.)

いくつかのオプションがある. 顧客は開発チームの人員構成に口をはさむことができる. "おたくの社員だけで開発してくれるなら, 何割か多めに払うよ" とか. また, 人員を追加するかわりにプロジェクトのオフィスを借りようと提案してもいい. 人件費数人分のオフィス代は, 一箇所に集る効率でじゅうぶん元がとれる. (どちらのオプションも実際に見たことがある.) いちばん手堅いのは, 機能を削るか納期を先送りすることだ. 思いつきの金メッキは空しい. 企業の会計年度に納品の足並みを揃えようと品質を損ねるのは悲しい.

こうした提案が現実的に思えない人は多いだろうし, 反論は色々あると思う. いちど開発の仕組みが分散スタイルに特化してしまうと, それを変えるのは難しい. (先の売上のジレンマに陥ってしまうなど.) これは, たとえるなら CORBA でソフトウェア資産をつくってしまったようなものだ. それを正す道は険しい. (ex. DeCOMtamination) まして組織や商習慣を変えるのはソフトウェアを書き換えるより時間も手間もかかる. 一方で自社開発に特化しガンガン開発を進めている組織は既にいくつもある. 成果に差がついてしまうのは仕方ない. (自社製品を作る組織の方がチームの構成に敏感なのは, 費用対効果が見えやすいせいもあるだろう.)

幽霊の影を逃れて

なんとか分散プロジェクトの誤謬から逃れられないものか. プログラマにできることは多くないけれど, 少しはある.

膨らみ続ける仕様と闘おう. ソフトウェアの規模が大きくなれば人が増える. 人が増えると組織をはみ出す. ソフトウェアは小さく保ち, 機能は注意深く選ぼう. 最初の仕様に書いてある機能はほとんど使われないハズレばかりだ. フィードバックを通して幽霊を見分けよう. 機能リストの項目数よりも, 速度や使い勝手といった品質に注力しよう.

雇用を捏造するのはやめよう. チームに人が増えたからといって, 無理に仕事を割りふるのはやめよう. 人員配置の正当化はあなたの仕事ではない. 冗長なモジュール分割, for-dummies なフレームワーク, 一ヶ月かけて作り一度しか使わないツール, 三ヶ月前のコードを逆エンジニアリングした文書, 誰もみない社内ウェブサイト, 立ち話の議事録, ホワイトボードの清書, 手動目視の単体テスト, 間違いだらけのサンプルコード... いくらでも仕事をつくることはできるが, そうした作業は目的に寄与しない. それどころかソフトウェアの品質を落としかねない. アーキテクチャは組織に従うが, 組織もまたアーキテクチャに倣う. 誰でも使えるフレームワークは, 誰でも使えるものしか使えない開発者を引き寄せる. 分散開発を許すコードは分散プロジェクトを招く. そんな挑戦を望むのでなければ, 無理に協力する謂れはない. (上司に脅されないうちは.)

分散させるな. 会社をまたぐな. 部署をまたぐな. フロアをまたぐな. ソフトウェアの開発は密なコミュニケーションを必要としている. 分散の境界は対話を妨げ, 効率を下げ, 意欲を挫き, 品質を落とすだろう. ソフトウェアを, チームを小さく保とう. きびきびと動く堅牢で身軽なコードを愛し, スケーラビリティの幽霊に別れを告げよう. さよなら.

... え? 来月から増員? 大阪のプロジェクトがキャンセルになったからリモートで仕事頼めるって? ...(保留音)... あ, どうもはじめまして. 来月から手伝って頂けるそうでエヘヘ. はい. そうですね. よろしくねがいします...