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 が Maven Central ではなく、Google ミラーからダウンロードされるのを確認できました。しかし、sbt 起動時などに sbt の本体などは引き続き Maven Central からダウンロードされていました。どうやら、  ~/.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 CentralGoogle Mirror
75パーセンタイル16.67 sec0.50 sec
中央値13.60 sec0.45 sec
25パーセンタイル10.88 sec0.44 sec
データ数2020

 75パーセンタイルで見ると Maven Central からは 16.67 秒(0.69 KB/秒)に対し、Google ミラーからは 0.50 秒(23 MB/秒)でダウンロードできてしまいました。

その差、33倍!
 
箱ヒゲ図にしてみると、

 

Google ミラーのほうは小さすぎて、なんだか分かりません!
 
ということで、33倍も高速な Google ミラーを使おう!
(効能は環境によって異なる場合があります)

 
 
 
 
 
 
 
 

……で済ませたいところでしたが、実際の Scala プロジェクト sbt がダウンロードするのは、このような大きめの JAR ファイルばかりではありません。ものによって数十 KB〜と大小様々ですし、それに加えて、数 KB のテキストデータ(POM ファイルなど)もたくさんダウンロードします。

ですので、実際のプロジェクトでどれくらい恩恵が感じられるのか、気になってきますね。

ということで、その点についても軽く調べてみました。

 

ぼくが関わっている、ある Scala プロジェクトを対象にしました。

  • Scala コード行数 22,000行
  • 依存関係
    • JAR ファイル数 1,193 個
    • POM ファイル数  585 個

このプロジェクトについて、coursier のキャッシュを削除して sbt でのダウンロードを繰り返したところ、ダウンロード時間の測定は


Maven CentralGoogle Mirror
75パーセンタイル51.04 sec38.88 sec
中央値47.41 sec37.66 sec
25パーセンタイル42.95 sec36.68 sec
データ数2020

となりました。箱ヒゲ図にしますと、

75パーセンタイルではダウンロード時間は25%短くなり、中央値(50パーセンタイル)では21% 短縮、25パーセンタイルでは 15% 短縮となりました。

Google ミラーによるダウンロード高速化の恩恵は、プロジェクトの規模などによるでしょうが、実プロジェクトに近いケース(大小様々な依存関係が大量)では、おおむね15〜25%程度、と言えそうです。

とはいえ、大きな JAR ファイル(Scala コンパイラなど)に更新があったとき、十数秒かかっていたダウンロードが1秒を切ることももあるのはうれしいでしょう。

 

 

結論

  • Google による Maven Central のミラーを使うと、ダウンロード時間が 15%〜25% 程度短くなる
  • coursier の mirror.properties に Google ミラーを設定すると、sbt を使ったすべてのプロジェクトで恩恵が得られる