嵐の後のBitkeeper(パート2)

このインタビューのパート1(opentechpress.jp)では、Linus Torvaldsらがカーネルパッチの処理にBitkeeperを利用して、生産性を大きく改善したことを説明した。インタビューの後半を紹介するこのパート2では、この生産性向上が意味するものを詳しく見ていく。

これまでにない多数のパッチが適用されるようになったのは、Linuxカーネルにとって吉だろうか凶だろうか。Bitkeeperの作者Larry McVoyと、LinuxのクリエイターLinus Torvaldsの両者に意見を聞いてみた。

Q:かつて「Linusのスケーラビリティ問題(Linus doesn’t scale)」が唱えられましたが、正しいツールを手に入れた彼がこの問題を解決したことは明らかです。そこで質問ですが、現在これほどのハイペースで進められるようになったLinux開発がLinusに多大な犠牲を強いたり、Linuxの品質低下を招くという懸念はないでしょうか。

McVoy:良い質問ですね。最初の質問は答えが長くなるので、後の質問からお答えします。

品質が低下しているとは思いません。Linuxを基盤として事業を展開していますが、Linuxの品質は着実に向上していますよ。カーネル機能の一部には全面的に賛成できない部分がありますが(たとえば、見せかけのリアルタイム性とか世界のコンピュータの0.001%でしか使われない細粒度のスレッド処理などです)、それらを選択したのは私ではありません。個人的な見解は抜きにして客観的に見れば、カーネルが一貫して改善されているのは確かでしょう。2.6はなかなかの仕上がりのようですし、変更の頻度も劇的に増えています。ペースアップが問題を招くとしたら、とっくにそうなっていてもおかしくないはずです。

1つ目の質問はもっと複雑ですね。短く答えるなら、Linusは犠牲を強いられるというよりは、以前よりもゆとりをもって、本来の仕事や、教育活動、センスの伝授、フィルタとしての活動などに、より多くの時間を割けると思います。彼とは定期的に会うのですが、以前よりも余裕を感じます。もっと忙しかった頃には関わらなかったような世の中のことに関心を向ける姿も見るようになりました。

ペースアップがLinusの負担増につながらない理由について、もっと長い答えもあります。まず背景についてご説明します。ソフトウェア開発には、一般的なモデルが2つあります。どちらも、他の部分を犠牲にする形で1つのことに最適化されています。ここでは「メンテナ」モデルと「商用」モデルと呼ぶことにします。

2つの開発モデル

メンテナモデルは、すべてのコードがフィルタの役割を担う一個人を経由するモデルです。このモデルは、周囲に認められたリーダーによってソースベースが管理される多数のオープンソースプロジェクトで使われています。長所は、ソースベースが乱雑にならないことです。粗悪な変更は拒否されます。短所は、作業が遅いことですね。メンテナがフィルタできる速さを超えて作業を進めることはできません。

商用モデルは、可能な限り早く変更がツリーにプッシュされるモデルです。これは「早期市場投入」モデルとも呼べるでしょう。多くの商用開発活動はメンテナモデルで出発しますが、市場経済では市場投入までの時間が生死を決めるので、やがて商用モデルに切り替えられます。市場に現れるのが早いことが商用モデルの長所ですが、品質管理がおろそかになるという短所があります。

  • 商用モデル:出荷が早い、品質が低い
  • メンテナモデル:出荷が遅い、品質が高い
  • メンテナ+商用モデル:出荷が早い、品質が高い

開発をスケーラブルにする

少人数での開発がやりやすいことは誰でも知っていますが、人数が増えるに従ってさまざまな問題が起こります。5、6人のチームなら、すべての変更をメンテナが管理する方法でうまくいきます。1人で間に合う作業ですから。

チームの人数を増やすと何が起きるでしょうか。商用開発とオープンソース開発はここで袂を分かちますが、どちらも痛みは大きくなります。

商用モデルでは、フィルタプロセスを省き、一刻も早く市場に出そうとします。数百人の開発者による作業を1人がフィルタしようとするのは、現実的ではありません。そんな大仕事をこなせる人はいませんね。市場経済の世界では、矛盾する2つの長所を両立させようと、さまざまなことが試みられてきました。経営者はスピードと品質を両立したいでしょうが、スピードをアップできるなら品質が犠牲にされるのが現実です。

メンテナモデルにもスケーラビリティは問題あります。メンテナが仕事をこなせる間はよいのですが、限界が来ると崩壊が始まります。多くのオープンソースプロジェクトでは、チームの人数が5、6人を超えないので問題はありません。少人数だと思うでしょうが、たいていの優れたものは少人数のチームで作られているのです。しかし、もっと人数の多いプロジェクトもあります。Linuxカーネル、X11、KDE、Gnomeなどがそうですね。一部のプロジェクトの規模は桁違いです。Linuxカーネルの2.5/2.6部門には、1,400人を超える人々が関わっています。彼らはBitKeeperを利用しています。

1,000人を超える人員の作業に1人の人間が追随するのは明らかに無理です。では、メンテナモデルでスケーラビリティを達成するにはどうすればよいでしょうか。分割して統治せよ、です。大勢の作業者と一人のメンテナで構成される基本単位を使うのです。メンテナを頂点とし、作業者を底辺とする三角形だと思ってください。最初はメンテナ一人と複数の作業者で構成される1つの三角形でスタートし、それ以上この三角形に入らなくなるまで作業者を追加していきます。三角形が満杯になったら、別のメンテナの階層を作成します。最上位のメンテナは、最上位の三角形が満杯になった時点でサブメンテナに仕事を委譲します。つまり、これまで作業者だった者をメンテナにするのです。サブメンテナの各人は2番目の階層の三角形でリーダーとなり、このような三角形が最上位の三角形の下に複数作られます。要するに、これは同じフィルタプロセスが複数の階層に適用されるlog(N)ファンインモデルです。

Linuxカーネルの場合、BitKeeperを使い始める前にこのモデルに移行していましたが、うまくいってませんでした。見逃されがちなことですが、階層化メンテナモデルでは、階層を追加すると作業者は正式なバージョンのツリーと変更中の全バージョンのツリーからどんどん離れていきます。ツリーから離れれば離れるほど、すべてのバージョンを1つにまとめるのに必要なマージが増えます。Linuxのサブメンテナは(Dave Miller、Greg KH、Jeff Garzikなど、いつも容疑者として槍玉にあげられる面々ですが)Linuxが新しいリリースを行うたびに「マージ地獄」を味わいました。メンテナモデルは、少人数のチームではうまくいきますが、人数が増えてくると「分割統治法」では避けられない難しいマージの繰り返しにサブメンテナは苦しめられます。

BitKeeperはメンテナモデルのスケーラビリティを改善する

BitKeeperは、メンテナモデルにも配慮して設計されました。マージなどの繰り返し作業を不要にすることで、メンテナモデルを(他のモデルと共に)実現します。メンテナモデルでは、部分的に異なる複数のツリーのマージや再マージを定期的に実施する作業が主体になると予想されるので、マージはBitKeeperの重要な機能でなければなりません。BitKeeperのマージ機能は、先ほど説明したモデルを実用化し、開発者が数百人から数千人に増えても耐えられるレベルにあります。BitKeeperがメンテナモデルに対応していることは、作業ペースが10倍にアップしたとサブメンテナがこぞって感じる大きな要因です。BitKeeperがすべてのマージ作業を代わりに片付けてくれるわけですから、作業負担の減ったサブメンテナが10倍のペースアップを感じるのは当然です。以前はもっと多くの仕事を抱えていましたが、BitKeeperがその大部分を解消したので、改善は劇的だったのです。

メンテナモデルのファンイン/ファンアウトは、Linusの負担が軽くなるという形でも現れています。信頼できる人物としてサブメンテナが参加すると、カーネルのサブセクションがやや自治性のあるサブプロジェクトとして分岐されます。Linusはサブメンテナと協力してフィルタ作業が適切に行われるようにします。これで、開発のスケーラビリティが少しアップします。

長々とご質問に答えてきたのは、変更の頻度が増えてもLinusが忙殺されない理由を説明するためです。メンテナと複数のサブメンテナを(そしてさらに下位のサブメンテナも)サポートできるツールがあれば、やがてサブメンテナのうち誰がフィルタ作業を得意とするのかが最上位のメンテナにはわかってきます。Linusは、そういった人物から受け取った変更については、多かれ少なかれ信頼してチェックを省きます。不適切な変更は、サブメンテナの手ですでに除外されていると見なします。サブメンテナの誰が実際にそれをやっているのかは経験で知っています。それ以外のサブメンテナから送られてきたパッチについては、1行1行じっくりとチェックします。

私の説明が悪くなければ、このモデルがスケーラビリティを提供できることがおわかりいただけたと思います。このようなlog(N)方式を使うと、非常に大きなNを簡単に扱えます。このモデルが目指しているのは、多数の開発者が参加する場合でも、変更をすばやく実行できて、なおかつ不適切な変更かどうかをチェックできることです。BitKeeperを使わずに膨大な作業を行う場合は、性急な商用モデルと、用心深いメンテナモデルのどちらかを選ばなければなりませんが、BitKeeperを使えば、両方のおいしいところを味わうことができます。作業は商用モデルに肉薄するレベルにペースアップしますが、ソースベースにとって規模の大小に関係なく重要である品質管理もおろそかにはなりません。

サブメンテナと協力して自分と同程度のレベルでフィルタ作業を行えるようにすることが今のLinusの仕事になっていると、ある程度までは言えます。「本来の仕事」も以前と同様にたくさんありますが、仕事の一部を他人でもできるようにすることで、スケーラビリティが実現されています。

Q:Linus、パッチの処理数が飛躍的に増えてからも、それまでと同じ種類の注意をパッチに向ける時間はありますか。

Torvalds:Larryが既に答えているので、おまけ程度のつもりで聞いてください。

私にとってBitKeeperのメリットは、私が信頼する人々や、各自のサブシステムを活発に保守する人々のことを気にかけなくて済むことです。マージ作業はどちらの側でも簡単になりましたし、ヒストリやコメントが失われることもありません。

ですから、BitKeeperのおかげでパッチの1つ1つに気を配る必要がなくなり、特別に注意する必要があるパッチに注意を集中しやすくなった、というのがご質問への答えです。そのおかげで、さらに多くのパッチを受け入れることも可能になりました。

そういった意味では、以前と「同じ種類の注意」ではありません。しかし、肝心なのは、そういった注意を向けられるからこそ、私が(さらに言えば他の人々も)より多くの仕事をこなせるようになったことです。

以前は「明白な」パッチを受けとるために忙殺されていました。信頼できる主だったサブシステムメンテナから送られてくるパッチのことです。仕事の大部分はこの種類のパッチのために費やされていましたが、注意の必要なパッチは比較的少ないのです。しかし、すべてがパッチで行われるので、「難しい」ケースでも「簡単な」ケースでも、常に同じ作業を行う必要がありました。しかも作業の相当な部分は、ただメールに目を通し、それをどのカテゴリに入れるか考えることに費やされていました。

BitKeeperは、この作業を助けてくれるのです。

また、BitKeeperには別の役割もあります。進捗状況をこれまでどおり把握しつつ、信頼できる人々にずっと多くの監督権を与えることを可能にします。

これまでのやり方では、複数の人間が同じソースツリーを操作する場合、全員が「書き込み可能アクセス権」を与えられてソース制御管理システムを使用します。そのため、厳密な「コミット」ルールを使用する必要があります。誰かがレビューを受けずに変更を適用することは、誰も望まないからです。そのため、「コミットレビュー」プロセスが限界点になります。このプロセスは、なあなあになるか(「後で直せばいいや」でうまくいったためしはありません)、厳格すぎて全員のブレーキになるか、2つに1つです。

対照的に、BitKeeperには分散型の性質もあるので、私は誰にも優先的な「書き込みアクセス権」は与えませんが、ある人が作業を終えて、何をしたかを連絡してくれた時点で、私たちの両方が同期を実行できます。パッチがレビュープロセスで「渋滞する」問題は起こりません。

そういった次第で、BitKeeperのメリットは、検討する必要があると私が感じること(あるいは向こう側からそうすべきだと依頼されたこと──実際はこのほうが多いですが)に専念できることのみならず、他人により多くの監督権を文字どおり譲れることです。そのおかげで、メンテナンス作業を任せることがずっと簡単になります。それこそが、BitKeeperが目指しているものなのです。