Google パワーで sbt でのダウンロードが33倍速くなる!?
この記事は Scala Advent Calendar 2022 の7日目が空いていたので、あとから投稿した記事です。アディショナルタイムみたいなものです。タイトルは釣りです(一応33倍速いという根拠はあとのほうに…)
ときに2015年、Google のエンジニアらが Maven Central のミラーを公開しました(以下かんたんのため Google ミラーと呼びます)。Google ミラーの目的は、Maven Central 上にある Java や Scala のライブラリなどを、Google のインフラのパワーで高速にダウンロードできるようにすることで、開発者体験を向上するためでした。その後の数年で多少書き方に変化あったようですが、簡素なトップページで Maven でのグローバルな設定方法が掲載されています。
さて、Scala で主流のビルドシステム sbt のグローバルな設定方法については、こちらに記載されています。要点だけ書きますと、ホームディレクトリにある ~/.sbt/repositories
というファイルに
[repositories]
local
maven-central: https://maven-central-asia.storage-download.googleapis.com/maven2/
sonatype-snapshots: https://oss.sonatype.org/content/repositories/snapshots
と書けば、Google ミラーがマシン全体に適用され、ダウンロードが高速化されます。日本からは maven-central-asia サブドメインが最速だと思いますが、その他の地域から利用するときは別のサブドメインを利用します。
カンタンですね!
Scala Steward などを利用して依存関係を頻繁に更新しているとダウンロードする機会も多くなりますから、ダウンロードが速くなるのはいいですね!
では Google ミラーを利用して、2023年も良い Scala 開発者人生をお送りください!
……で済ませたいところでしたが、そうはいきませんでした。
~/.sbt/repositories
を無視するケースがあるようです。なぜでしょう? この記事での興味はその技術的詳細ではないので結論だけ述べると、Couriser のグローバル設定でミラーを設定する必要がありました。その設定ファイルは OS によって置き場所が異なります(Coursier のドキュメントでは分かりにくく、 metals のドキュメントから孫引きとなります)。
- Windows: C:\Users\<user_name>\AppData\Roaming\Coursier\config\mirror.properties
- Linux: ~/.config/coursier/mirror.properties
- MacOS: ~/Library/Preferences/Coursier/mirror.properties
この mirror.properties ファイルに、
central.from=https://repo1.maven.org/maven2
central.to=https://maven-central-asia.storage-download.googleapis.com/maven2
と書けば、SBT 本体のダウンロードなどにも Google ミラーが適用されます。最初に紹介した ~/.sbt/repositories
はもう必要ないようです。
カンタンですね!
それではよい2023年を!
……で済ませたいところでしたが。
Google ミラーを使うことで、実際にどれくらい高速化するのか?
気になってしまいました。
ということで、軽く調べてみました。
単独の JAR ファイルとしては比較的大きめ(10 MB 超え)で Scala ユーザーなら誰しも利用している Scala コンパイラーの JAR について、ダウンロード時間を計測してみました。
- Scala 2.13.10 コンパイラーの JAR ファイル 11.5MB
- Maven Central: https://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.13.10/scala-compiler-2.13.10.jar
- Google ミラー: https://maven-central-asia.storage-download.googleapis.com/maven2/org/scala-lang/scala-compiler/2.13.10/scala-compiler-2.13.10.jar
ダウンロード時間の測定結果は次のようになりました。
Maven Central | Google Mirror | |
---|---|---|
75パーセンタイル | 16.67 sec | 0.50 sec |
中央値 | 13.60 sec | 0.45 sec |
25パーセンタイル | 10.88 sec | 0.44 sec |
データ数 | 20 | 20 |
75パーセンタイルで見ると Maven Central からは 16.67 秒(0.69 KB/秒)に対し、Google ミラーからは 0.50 秒(23 MB/秒)でダウンロードできてしまいました。
その差、33倍!……で済ませたいところでしたが、実際の Scala プロジェクト sbt がダウンロードするのは、このような大きめの JAR ファイルばかりではありません。ものによって数十 KB〜と大小様々ですし、それに加えて、数 KB のテキストデータ(POM ファイルなど)もたくさんダウンロードします。
ですので、実際のプロジェクトでどれくらい恩恵が感じられるのか、気になってきますね。
ということで、その点についても軽く調べてみました。
ぼくが関わっている、ある Scala プロジェクトを対象にしました。
- Scala コード行数 22,000行
- 依存関係
- JAR ファイル数 1,193 個
- POM ファイル数 585 個
このプロジェクトについて、coursier のキャッシュを削除して sbt でのダウンロードを繰り返したところ、ダウンロード時間の測定は
Maven Central | Google Mirror | |
---|---|---|
75パーセンタイル | 51.04 sec | 38.88 sec |
中央値 | 47.41 sec | 37.66 sec |
25パーセンタイル | 42.95 sec | 36.68 sec |
データ数 | 20 | 20 |
となりました。箱ヒゲ図にしますと、
75パーセンタイルではダウンロード時間は25%短くなり、中央値(50パーセンタイル)では21% 短縮、25パーセンタイルでは 15% 短縮となりました。Google ミラーによるダウンロード高速化の恩恵は、プロジェクトの規模などによるでしょうが、実プロジェクトに近いケース(大小様々な依存関係が大量)では、おおむね15〜25%程度、と言えそうです。
とはいえ、大きな JAR ファイル(Scala コンパイラなど)に更新があったとき、十数秒かかっていたダウンロードが1秒を切ることももあるのはうれしいでしょう。
結論
- Google による Maven Central のミラーを使うと、ダウンロード時間が 15%〜25% 程度短くなる
- coursier の mirror.properties に Google ミラーを設定すると、sbt を使ったすべてのプロジェクトで恩恵が得られる