25
Build is Money 発表者 : 僻地のプログラマkmt-t

Build is money

Embed Size (px)

Citation preview

Build is Money発表者 : 僻地のプログラマkmt-t

自己紹介

ハンドルネーム

正式には「kmt-t」

Twitter IDは「kmt_t」

はてなIDは「kmt-t2」

居住地

鳥取県出身ですが大阪に出稼ぎ中です。

鳥取本社の会社に転職したのでいつか実家に帰る予定。

所属クラスタ

転職前まで組み込みの仕事をしていた関係で組み込みクラスタです。

言語はC++、C#あたりが得意です。

話の前振り (1/2)

昔からの疑問

某キャリア向け携帯電話開発をしていたとき

ソースコードは1000万ステップ超え。

当時(5年ぐらい前)のPCでビルド時間が3時間程度。

ビルド当番および各担当者は死ねる。

何でビルドサーバを用意しないのか?なんだかなー。

趣味でAndroidのソースコードをビルドするとき

特に最近(4.0以降)はソースコードがめちゃくちゃでかい!

ネットブックなんかでビルドすると余裕で10時間コース。

これどうにかならんの?

話の前振り (2/2)

湧き上がる欲望

人間は欲深い

ビルドを速くしたい!

でもお金はあまりない!

ここからビルドを高速化するための長い旅が始まる…。

ビルド高速化のための一般的な手法(1/4)

スケールアップ

単に速いPCを購入する。

一番手っ取り早いし、王道。

実は効率はかなりよい

業務では遅いPCで仕事することが多いが、実は一番安くつく。

一日一時間ビルド時間を短縮できれば一か月でコストをペイできる。

経費の処理はいろいろ面倒臭いよね

ビルド高速化のための一般的な手法(2/4)

ビルドサーバの導入

ビルド専用のサーバを立てる

一台の高速なPCを数名でシェアする。

Linuxだとマルチユーザ環境を作りやすいのでシェアするのが簡単。

WindowsだとシェアするにはRDS、VDIといった技術が必要でハードル高い。

さらなる効率的な運用のためのキーワード

ロードバランサ

仮想化

ビルド高速化のための一般的な手法(3/4)

並列ビルド

ビルドを複数のジョブに分割し、複数のプロセッサコアで並列処理する。

Linuxだと「make –j (ジョブ数)」

WindowsだとVisual Studioの設定が存在する。

デフォルトのジョブ数が4になっているが、調整して使ってない人も多いかも。

ビルド高速化のための一般的な手法(4/4)

分散ビルド

ビルドを複数のジョブに分割し、複数のPCで分散処理する。

Linuxの場合わりと簡単に分散ビルド環境を構築できる。

distcc

Icecc

Jenkins(本来は継続的インテグレーションツール)

組み込み開発でも問題なく使える。

ただし問題がないわけでもない。

あとで説明する。

Windowsの場合も有料ソフトを使えば分散ビルド環境を構築できる。

マイクロソフト製「Team Foundation Server」(6万円程度)

その他にもいくつかあるらしい。

ビルドを極める長い旅 (一般人期)

パソコン工房編

事の発端

当時は無印BeagleBoadが発売されたばかり。

Angstromという組み込み向けLinuxディストリビューションをビルドしたい。

ちなみにニコニコ動画の動画を機械学習で自動収集というあほな装置作ってました。

困ったことに

Xeon(Woodcrest)/2コア/1.6GHzでビルドに10時間ぐらいかかる。

ビルドを開始してから寝る生活。

自分のアクション

パソコン工房に行って「速いPC下さい!」(C2Q/3GHzのPCを買った)

3時間ぐらいでビルドできるようなったが、正直まだ不満。

ビルドを極める長い旅 (入門期)

並列ビルド導入編

事の発端

BeagleBoardでAndroidを動かしたい。

時期的にはEclair(2.0-2.2)あたりの時期。

困ったことに

先日買ったC2QのマシンでもAndroidのビルドに数時間かかって遅い。

新しいアクション

makeの-jオプションで並列ビルドできるらしい。

これにより1時間ぐらいでビルドできるようになった。

これぐらいならまあまあ満足かな。

ビルドを極める長い旅 (入門期)

コンパイルキャッシュ導入

事の発端

cccacheというコンパイルキャッシュを使うと速くなるという情報入手。

新しいアクション

環境変数に「export USE_CCACHE=1」を設定するだけOK。

45分かかっていたGingerBreadのビルドが2回目以降15分になる。

しかし自分の心に異変が

目的がビルド時間を短縮することになってくる。

なのでキャッシュなしでも速くしたい!

ビルドを極める長い旅 (欲望肥大化期)

分散ビルド導入編

個人ユースでは禁断の手法、分散ビルドに手を付ける

分散ビルド用にNTT Xストアから1万円のサーバを調達。

正直やりすぎ。

以下の設定でAndroidの分散ビルドが可能

環境変数に「export USE_CCACHE=1」。

環境変数に「export CACHE_PREFIX=distcc」。

distccの設定を各マシンにしておいて「distcc-pump make –j xx」でビルド。

しかし問題はある

確かにいくらか速くなる (3台構成で20~30%ぐらい)がうまくスケールしない。

ログをみるとサーバごとのジョブの割り当てのバランスが悪かったりする。

ビルドを極める長い旅 (欲望充足期)

クラウドビルド編

ほぼ完ぺきなソリューションに到達!

AWS万歳!!!

クラウドビルドの何が完璧なのか?

クラウドにはAWS(Amazon Web Service)を使った

とにかく速い

単体CPUの速度はデスクトップと遜色ない。

2ソケットの仮想マシンも用意できるのでコア数はデスクトップより多い。

ネットワークが高速で「repo sync」は家庭用FTTHの10倍ぐらい出る。

ストレージは内部的にSANに束ねているようなので微妙に遅い。

ストレージは仮想化されてるので台数を簡単に増やせる。

よってRAIDが自由に組めるので問題なし。

とにかく安い

どれぐらい安いかはあとで述べる。

ベンチマークのリファレンスマシン

基準となるマシンのビルド時間

Twitterで募集したところ、@zaki50先生が測ってくれました。

スペック

CPU Intel Core-i7 [email protected] (6コア) HT付

メモリ 32BG

家庭用で購入できるマシンとしては最速!モンスターマシン!

結果

ビルド時間 25m46.132s 2012年9月18日時点でのAOSP/masterブランチ。

make –j24

Androidのソースをビルドしたことのある人ならわかるが、笑っちゃうほど速い。

とりあえずAWSでビルドしてみた

インスタンス(仮想マシン)は「ハイメモリクアドラブルエクストララージ」

普通に使えるAWSのインスタンスとしては最強。

スペック

CPU Core i7 3GHzぐらいの性能 (8コア)

メモリ 68.4GB

コア数ではリファレンスマシンに勝っている。

結果

ビルド時間 43m5.901s 2012年9月時点のAOSP/masterブランチ。

make –j 16

やっぱり負けた…orz

最終奥義クラスタコンピュートエイトエクストララージインスタンス!

AWSにはアメリカの一部AZ(データセンターのグループ)でしか使えない巨大なインスタンスが存在する

クラスタ計算用のインスタンスみたい。

名前が最終奥義っぽい。

スペック

CPU Intel Xeon E-2670 (8コア) x 2ソケット

メモリ 60.5GB

I/O性能 10Gbitイーサネット これならいくら何でも@zaki50先生に勝てるっしょ!

最終奥義の結果

計測結果

ビルド時間 21m41.659s 2012年9月時点のAOSP/masterブランチ。

make –j 32 感想

とっておきだったのに思いのほか差は出ず。

@zaki50先生のマシン強すぎる。

圧勝したい、どうしても圧勝したい!

自分の中で納得感が低い

基本的にこの発表はAWS万歳な発表なので、どうしても@zaki50先生のマシンを蹂躙できないと困る。

distccで分散ビルド?でも並列化は限界だと思うのであんまり速くならなそう。

最終奥義インスタンスのスペックの再確認

CPU Intel Xeon E-2670 (8コア) x 2ソケット

メモリ 60.5GB

I/O性能 10Gbitイーサネット

そうか、その手があったか!

超最終奥義RAMディスク

メモリが大量に余っているので20GBほどRAMディスクにする

ビルドのワークおよび出力ディレクトリをRAMディスクにする

export OUT_DIR_COMMON_BASE=<path-to-ramdisk>

結果

ビルド時間 16m6.900s 2012年9月時点のAOSP/masterブランチ。

圧 勝

ご利用料金

インスタンス料金

クラスタコンピュートエイトエクストララージインスタンス

1時間当たり0.25ドル (日本円で20円)。

スポットインスタンス(値段は時価で変動するインスタンス契約)。

EBS (ストレージ) 料金

50GBでデータ保存料金は月500円ぐらい。

I/Oリクエスト料金

1回のビルドで0.1ドル (日本円で8円) ぐらい。

フルビルドの時だけでかいインスタンスを使う運用なら月2000円もしない

20万円のPCを買ったとするとAWSとトントンになるのは100か月後。

AWSは勝手に新しいマシンにリプレイスするが、それには料金発生せず。

自分のユースケースでいくらかかるかは以下のサイトで概算できる

http://calculator.s3.amazonaws.com/calc5.html

Amazon本気で儲かるのか!?

注意点

契約タイプの注意事項

AWSにはいくつかの契約タイプがある。

スポットインスタンスだと一時的に使用する場合はかなり安いが、時価の変動によりいきなりシャットダウンさせられる可能性あり。

リザーブインスタンスだと前金を払うことにより長時間運用で安くなるが、割引率はそれほど高くない。

クラスタ向けインスタンスの注意事項

一部のAZでしか使用できない。

仮想マシンのイメージがほかのインスタンスタイプとは違い、完全仮想化されたものが必要。コミュニティAMIで「cluster」とか「HVM」と付いたものを探す。

ちなみにAWS以外のIaaSは話にならないほど高いです

さらなる高速化に向けて

新たな目標として10分切り!

Androidビルド界の重鎮JBQ氏曰く、「“15 minutes isn‘t bad. If you want to go faster,」!

distccの導入

某社では20台でdistccクラスタを構成しているらしい。

RAMディスクの適用範囲の拡大

ccacheのディレクトリ

ソースディレクトリ

今後、Amazonが超巨大インスタンスを提供するらしい

http://jp.techcrunch.com/archives/20121129amazon-announces-2-new-ec2-instance-types-cluster-high-memory-with-240gb-ram-and-high-storage-with-48tb-hdd-space/

おまけ1

「make –j XX」の最適な設定

CPUのコア数とmake -jオプションのジョブ数との関係

@kinneko先生に調べていただきました。

http://d.hatena.ne.jp/kinneko/20120919/p1

要約すると物理コアx2ぐらいのジョブ数が最適。

それ以上になるとメモリは食うけど速度は変わらない。

ひそかにメモリ重要。

ジョブ数x1GBぐらいメモリがないとスワップする。

おまけ2

「repo sync」の高速化

Androidのソースをローカルサーバにミラーする

repo init -u https://android.googlesource.com/platform/manifest --mirror

repo sync

以上でミラーのベアリポジトリができる。

自分がミラーしたいバージョンのmanifest.xmlを入手

普通は取得したソースの「.repo」ディレクトリにある。

manifest.xmlの<remote>タグをミラーのベアリポジトリURLに書き換え。

URLにはGit、WebDAV、SSHプロトコルが指定できる。

manifest.xmlを自分で作成した新しいGitリポジトリに登録する

書き換えた「manifest.xml」で「repo init」する。

-uオプションは書き換えたmanifest.xmlのリポジトリURL。

-bオプションは書き換えたmanifest.xmlのリポジトリのブランチ名。

ソースコードのブランチ名ではない。

-mオプションはmanifest.xmlのファイル名 (manifest.xmlをリネームした時に使用)。