Skip to content
Latchkey

より速いCIのための依存関係cache戦略

最大で最も安価なCIの高速化は、実行ごとに同じ依存関係を再ダウンロードしないことだ。package storeをcacheし、lockfileでkey化すれば、ほとんどのインストールがほぼ瞬時になる。

依存関係のインストールは多くのCIのjobを占める。良いcache戦略は前の実行からpackage storeを復元し、インストーラが実際に変わったものだけを取得するようにする - 数分を数秒に変える。

プロジェクトではなくstoreをcacheする

node_modulesのようなプロジェクトディレクトリよりも、パッケージマネージャのグローバルstoreやdownload cache(npm cache、~/.m2、pip wheel cache、Cargo registry)をcacheするほうがよい。storeはポータブルで、copyされたファイルを盲信するのではなく、インストーラに速く検証済みのインストールをさせられる。

lockfileでkey化する

cache keyは、依存関係が変わったときちょうど変わるべきだ - lockfile(package-lock.jsonpoetry.lockCargo.lock)のhash。同じlockfile → 同じcache → 完全hit。変わったlockfile → 新しいcacheエントリ、そしてrestore-keyのfallbackが前のstoreの大部分を回復する。

Lockfile-keyed cache
key: deps-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
  deps-${{ runner.os }}-

よくある落とし穴

  • 常に変わる値でkey化する → hit率0%。
  • node_modulesを直接cacheし、lockfileのdriftを隠す。
  • keyにOS/archを含めない → 互換性のないバイナリを復元する。
  • 無効化より速くcacheし、古い推移的depsを提供する。

見返りを測る

cache hitとcold実行でインストール時間を比べる; 似ているなら、cacheはhitしていない。健全な依存関係cacheは、数分のインストールを数秒に変えるべきで、hit率はlockfileに触れないbranchで高いはずだ。

重要なポイント

  • 解決済みのプロジェクトディレクトリではなく、package store/download cacheをcacheする。
  • lockfileのhashでkey化する; ニアミスのfallbackにrestore-keysを使う。
  • 互換性のないバイナリを復元しないよう、OS/archを含める。
  • hit vs coldのインストール時間を比べて検証する - 似ているならhitしていない。

関連ガイド