読者です 読者をやめる 読者になる 読者になる

ninjinkun's diary

ninjinkunの日記

Google 工藤拓さん講演「大規模ソフトウェア開発を支えるGoogleのテクノロジー」

NAISTにてMeCabの作者としても有名な工藤拓さんの講演が行われました。Googleの開発体制とそれを支えるツールのお話です。
学校と拓さんの双方からブログへの掲載許可が得られたので、まとめを公開します。この講義はNAISTのソフトウェア開発管理講義の一環です。


iPhoneカメラしかなかったので、画像が荒くて済みません・・・。

会場は大入り!

工藤拓さん

  • NAIST自然言語処理学講座出身
  • Googleに入社してから大規模開発やインフラを経験
  • MeCabを開発
  • NTTコミュニケーション科学基礎研究所に所属
  • その後Google
    • 研究より開発寄り
  • Googleでの仕事
    • 日本語のウェブ検索
    • 「もしかして」機能
    • ダジャレサーチ
      • エイプリルフールネタを1ヶ月かけて実装

コードレビューとは

  • 一人の開発者がコードを書いた後、別の開発者がそのコードをレビューする
    • コードレビューも含めてコーディング
    • 一行一行丁寧にレビュー
  • あら探しがゴールではない
    • 開発者間の協力
    • コーディング全体における一つのプロセス
  • 誰かのコードをデバッグ中に「不本意に」コードレビューを行うことがある
    • 感情的になりがち
    • 良いことではない
  • はじめからコードレビューをするという前提に立つ
メリット
  • 早期のバグ発見
  • コーディングスタイル規約を強制できる
  • 新人の研修目的
    • 既存のシステムを壊すことなく多くのことを学ぶことが出来る
    • 壊しそうになっても事前に止められる
  • 開発者間の信頼関係を築く
    • システムの引き継ぎが容易
    • 次のプロジェクトに行きやすくなり、流動性が高まる
  • ペアプログラミングの良い代替手段
    • 地理的・時差的に離れた開発者間で共同開発
    • 世界に分散しているため
OSSプロジェクトでのコードレビュー
  • 開発者がdiffコマンドでパッチを作成
  • レビュワにパッチを送る
  • メールやSourceForgeのpatch managerを使う
  • レビュワはpatchコマンドを使い差分を手元のファイルに適用する
  • 開発者とレビュワがメールでやりとり、内容を確認
  • レビュワが変更をレポジトリにサブミット
  • 信頼関係を築いた後で権利を譲渡
Google開発プロセス
  • 全社的に単独のPerforce (p4)リポジトリ
    • 開発者・プロジェクト毎にブランチは基本的にない
  • 全社的なNFS環境
    • 他の開発者のワークスペースを世界中のどこからでもアクセスできる
    • アメリカのホームディレクトリも見れる
  • チェックインされる全てのコード・パッチはサブミットの前に必ずレビューを受けなければならない
    • 例外はない
    • コードレビューのやりとりのメール誰でも参照できるように永久保存される
  • p4を直接使わずにg4というラッパープログラムを使っている

Googleのコードレビュー(以前)

1. 該当のコードをレポジトリからダウンロード(チェックアウト)
2. コードに変更を加え、テストを行う
3. ChangeList(CL)を作り、レビュワにメール

  • CL:変更されたファイル名、パッチに対応づけられたID番号
  • 以降Clで変更が管理する

4. レビュワとのメールのやりとり
5. レビュワがLGTMと返信するとサブミット出来る

  • LGTM = Looks good to me
以前のコードレビューツール
  • g4 change 変更点をまとめたChangeList IDを作成
  • g4 mail ChangeListをレビュワに送信
  • g4 diff レビュワが変更点を各員
  • tkdiffをデフォルとして使っていた
  • g4 subumit
以前のシステムの問題点
  • VPNフレンドリーではない
    • 自宅から作業するかも知れない
    • Tkdiffが動かない、動いたとしてもとても遅い
  • 行番号の更新が困難
    • 良く和あるコメント「行番号のここをこう変更して」
    • 行番号に対応づけられたコメントが更新されない
  • レビュー中の任意の時点でのリビジョンとのdiffがとれない
  • レビュワが全てのリビジョンを管理する必要がある
  • メールの山に埋もれてしまう
    • レビュワ:このレビューは終わったんだっけ?
    • 開発者:私のレビューは始まったのかしら?

Mondorian

  • Guido van Rossum (Python作者)を中心に開発されたコードレビューシステム
  • Webベース
    • VPNの問題がない
    • 全てのリビジョンがサーバ側で管理されている
  • 変更をside-by-side diff で表示
  • コメントをインラインで挿入可能
    • Ajaxを使いまくり
    • 複数のコメントは自動的に一つのメールにまとめられる
    • リビジョン毎に行番号が管理される
    • メールベースの従来の管理もサポート
  • 個人のダッシュボード(ポータルサイト)
Mondorianの中身
  • Bigtableを使用
    • ChangeLisのメタデータ(コメント、ファイル名リスト)
    • コメント(レビューのやりとり)
    • 開発者のホームディレクトリにあるコードのスナップショット
    • ユーザ毎の情報
  • ホームディレクトリ、bigtable,perforceと通信
    • NFSもしくはSSHを用いてホームディレクトリにアクセス
  • メールの管理
スナップショット
  • ユーザのホームディレクトリにある変更中のファイルをMondrianが知る必要がある
    • Mondrianにアクセスする度に更新する必要がある
    • エディタでの変更履歴を全て確認可能
  • ユーザのスナップショットがNFS上にない場合
    • SSHを使いユーザのLinux Boxに直接アクセス
  • スナップショットやコメントは永遠に保存される
    • 後々参照するのに便利
    • 同じようなことを試みている別の開発者にCLを指し示すことが出来る
パフォーマンス
  • 多くの場合十分高速
  • ほとんどの開発者はMondrianのみを使っている
  • 多くの処理はMondrianの外
  • 何が遅いのか?
    • Perforceサーバの高負荷
    • HTMLの生成
    • 巨大なファイルのdiff (Pythonのdifflib)
  • レビュワはコードにimpressionを付けられる!
    • looks good to me!
  • コードにコメント書ける
    • コメントにもレスが書ける
    • 改変して、レスを付けてdoneすればOK
チェックイン
  • 何回かレビュワとのやりとり
  • レビュワがApproval
Rietveld オープンソース版Mondrian

Protocol Buffers

  • Googleが開発した構造化データのデータ交換
  • C言語の構造体のような定義ファイル(*.protoファイル) から, C++, Java, Pythonのコードを生成
なぜProtocol Buffers?
  • XMLに対するアドバンテージ
    • バックエンド、フロントエンドで使える共通のデータフォーマット
    • バックエンドC++, フロントエンドJava, 社内ツールPython
    • GmailのフロントエンドはJava
  • フォーマットのバージョンアップに頑健
    • フィールドidが同じなら互換性が確保される
    • 新しいデーターフィールドが追加削除されてもidが同じなら動く
  • CPU、ネットワークの負荷を小さくしたい
    • 数千大、数万台規模のRPC
    • XMLのPersingは遅い、冗長、資源を使用しすぎる
    • XMLより3~10バイコンパクト
  • 大規模開発に有益
    • フォーマットやエンコード方法を完全に隠匿
    • データ交換フォーマットを議論しなくて良くなる
    • 言語に組み込まれるので直感的に操作可能
Google社内でのProtocol Buffes
  • バックエンド・フロントエンド間のRPC
    • Web検索フロントエンド
    • スペルチェッカーバックエンド
    • インデクサーバックエンド等
  • ログの保存
    • タイムスタンプなどの様座万情報
  • クロールしてきたWebドキュメントの保存

glfags

  • Googleが開発したコマンドラインフラグのParser
  • %foo --big_menu --language japanese
  • getoptととの比較
    • getoptはコマンドラインの定義をmainの中に集中管理
    • gflagsはコマンドライの定義を個々のソースに分散管理
なぜgflags?
  • 大規模開発でgetoptを使うと
    • 自分のコマンドラインを追加したい!
    • main関数があるソースを探し、そこに定義を追加
    • コマンドラインの内容を適当にディスパッチ
    • 煩雑な手続き、その課程でバグが混入
  • gflagsでは
    • 自分の編集している*.ccファイルにフラグを追加してビルド
    • 即座に反映
  • 実験機能の追加に有益
    • 既存のシステムを壊さない

その他

  • Open source化されたGoogleの開発ツール
    • glog
    • perftool
    • gtest
    • google C++ coding style guide

まとめ

  • 大規模ソフトウェア開発を支えるGoogleのインフラストラクチャ
    • Mondrian
    • Protocol Buffes
    • gflags

質問タイムのまとめ

質問をメモしていないなかったので、拓さんの発言だけをまとめてあります。

  • 突然レビュー依頼が来ることもある
  • Googleでは週報が義務づけられている
    • 最近コードを弄った人かも分かるので、レビュワを依頼しやすい
  • Experiment用のリポジトリがある
    • 基本的にレビューなし
    • しかしExperimentalからリンクしようとするとビルドツールに怒られる
  • Readability Review
    • コード規約レベルでのレビュー
    • 各言語の規約に精通したスペシャリストたちがレビュー
    • 本当に細かくチェックされる
    • 誰でも規約に沿ったコーディングができるように!

公演後の交流会

基本的にメモをとっていなかったので、印象に残ったことだけ・・・。

MeCabストーリー
  • ナナロク世代、大学入学とインターネットの黎明期がリンクしていた
    • 京大で3MBのホームディレクトリに4MBのNetscapeをどうやって入れるのかとか考えていた
  • 黎明期の日本語検索エンジンを使ううちに、検索をやりたいと思うようになり、NAIST松本研に進学
    • 既にChaSenがあり、OSSで成功していた
  • Outputを積極的に出して行く雰囲気
    • 論文を書いたら必ずソースも一緒に公開していた
  • ChaSenはJumanをベースにしているため、コードベースが古かった
    • メンテがしんどくなり、フルスクラッチで開発
    • MeCab誕生
拓さんからのメッセージ

短期的な視点と長期的な視点、両方を持つ必要がある。長期的な視点で取り組めるのは学生のうち。会社に入ると短期的な視点で取り組むことが多くなる。長期的な視点を忘れないことが重要。

10/24 20時 追記

はてなとの比較をして欲しいというリクエストがありました。僕はインターンをした際の知識しかないので、あまり大きなことは言えないのですが、一応書いてみます。
インターンはみんなペアプロをしていたので、自動的にコードレビューをしていた感じでした。また基本的に数千人もの開発者がいるGoogleと、数十人のはてなではかなり規模が違います。はてなでもレビューはやっていますが、専用のシステムもありませんし、行ごとにコメントを付けるようなこともしていなかったように思います。ただ、開発者が1フロアに集まっているため、コミュニケーションのコストはあまり高くありません。そのために当事者間で結構解決してしまっている気もします。evidenceを重視するのであれば、専用のシステムが必要かもしれませんね。(コミットログである程度はできると思いますが)
偉そうに書いてしまった・・・。違ってたら指摘をお願いします−。

さらに追記

拓さんにメールを送って、この記事をレビューして貰いました。

LGTM

happy hacking!

と言ってもらえました!

10/27 追記

はてなにもレビュー管理システムがありました。タスク管理システムの「あしか」と統合されているようです。

git コミット単位での参照・レビュー・担当者関連づけ・メール飛ぶとかいろいろあるのになー。

インターン期間中は使っていなかったため、誤った情報を伝えてしまいました。id:secondlifeすみません!