emergeの高速化、もしくはメタデータキャッシュの話
eixはeix-updateで自前のキャッシュを作りますが、この時のソースがいくつか用意されています。
- 個別のebuildを直接読む(parse, ebuild)
- 当然時間がかかります。また"ebuild"の場合はebuild(中身はシェルスクリプト)を実行するので、信用できないoverlayで使うべきでないとeixのmanには書かれていますね。
- treeごとのキャッシュを使う(metadata-flat, metadata-md5, metadata-assign)
- 例えば/usr/portage/metadata/以下にあるやつです。gentooツリーの場合はこのキャッシュごと同期するので、ローカルで生成しなくても使えます。
- emergeで生成するキャッシュを使う(flat, cdb, assign, sqlite, 多分repo-*も)
- 通常/var/cache/edb/dep/以下にあります。emerge --metadataなどで生成します。
- eixのキャッシュファイルを使う(eix)
- 通常/var/cache/eix/以下にあります。
これはeixから見た話ですが、同じようなことをemergeでもしてるはず。
eixは何も考えなくても速いのでいいんですが、emergeはそのままだとなかなか依存解決に時間がかかるので速くしたいですね。
ということで色々比較。
環境
gentoo, local, gentoo-haskell, betagarden, sunriseが入ってます。
ちょうどhaskell-platformすら入っていない状態なので、emerge -p yesod-platformの時間を計ります。
ちなみにキャッシュ破棄した状態だとこんな感じ。
$ sudo rm -rf /var/cache/edb/dep $ emerge -p yesod-platform real 1m1.100s user 1m24.869s sys 0m18.156s
肝心のhaskell overlay以外も入ってるし、一回分のtimeそのままという適当さなのでほんとにざっくりですが。
emerge --metadata
emerge --syncしたときに勝手に走るようですが。eixから見たflatやassign。
$ sudo emerge --metadata real 0m13.520s user 0m12.737s sys 0m0.760s $ emerge -p yesod-platform real 0m36.400s user 0m27.230s sys 0m5.042s
30秒って数字で見るとたいしたことなさそうですが、なかなか長く感じます。
md5-cache
treeごとのキャッシュのひとつで、gentooツリーでも使われています。eixから見たmetadata-md5。
egencacheというコマンドで生成します。細かいことは後述。
$ sudo rm -rf /var/cache/edb/dep $ sudo egencache --repo=gentoo-haskell --update --update-use-local-desc real 1m22.179s user 0m54.974s sys 0m12.471s $ emerge -p yesod-platform real 0m28.985s user 1m1.687s sys 0m13.470s
--metadataだけと比べて、userはあまり変わってないもののrealが短くなってますね。
/var/lib/layman/haskell/metadata/md5-cache/ができています。
ここでさらに--metadata。
$ sudo emerge --metadata real 0m19.451s user 0m15.896s sys 0m1.605s $ emerge -p yesod-platform real 0m4.473s user 0m4.397s sys 0m0.060s
速い。
試しに上で生成したgentoo-haskellのキャッシュを消してみましたが、変わりませんね。同じようにemerge --metadataを実行しても、元の形式によって変わるのでしょうか。。
sqlite
wiki.gentoo.orgができるまえのGentoo Wikiに記事があった方法です。
http://www.gentoo-wiki.info/TIP_speed_up_portage_with_sqlite
という時点でobsolete臭がするのですが、以前使っていた記憶があるのでこれも試してみます。
$ sudo vi /etc/portage/modules $ sudo emerge --metadata real 0m20.192s user 0m17.771s sys 0m2.379s $ emerge -p yesod-platform real 0m36.443s user 0m27.226s sys 0m5.068s
/var/cache/edb/dep/var/lib/layman/haskell.sqliteが生成されてはいますが・・・sqlite使わない場合とあまり変わりませんね。
md5-cacheと組み合わせてみましょう。
$ sudo egencache --repo=gentoo-haskell --update --update-use-local-desc $ sudo rm -rf /var/cache/edb/dep $ sudo emerge --metadata real 0m21.745s user 0m18.898s sys 0m2.588s $ emerge -p yesod-platform real 0m4.701s user 0m4.922s sys 0m0.230s
これまたsqlite使わない場合と変わりませんね・・・。
eixのmanを見ると、portage-2.1以上でデフォルトのキャッシュがflatからassignに変更されているようです。flatの頃は今より遅く、cdbという非公式拡張や、今回試したsqliteなどが使われていた、というところでしょうか。
まとめ
大きなoverlayを使う場合はtreeごとのキャッシュを作ると良さそうです。というか、eixのmanにはSPEEDUPというセクションがあり、そういう話が書いてあります。自動で走らせる方法や注意点なども書いてあるので読みましょう、英語だけど。
ハウツー的なのをQiitaに書いたので読みたい方はこちらへ。
http://qiita.com/unarist@github/items/c1afa5ddfc7da1337b11
参考
*1:ここには--regenを使った方法が書いてあるけど、--metadataでいいんじゃないかなあ。assign使うとしてもegencacheで変化するのは上に書いたとおり。