LoginSignup
9
1

More than 3 years have passed since last update.

Go Modules のダウンロードを高速化する Module Mirror と Module Index, Module Checksum Database について

Last updated at Posted at 2019-07-27

はじめに

2018年末に Go の開発チームが 2019年 の Go Modules に関する計画を Go Modules in 2019 - The Go Blog で公開しました。

ブログの中では、Go 1.11 から提供された Go Modules1 の説明から始まり、go get で行えたことを Go Modules でも実現することの重要性2 や、コードの分散管理が許容されることの欠点3 に触れた後に、Go チームでの Go Modules に関する計画が書かれていました。4

今回は、当時 Go Modules に関する計画として紹介されていて、最近になり アルファテストの提供開始がアナウンスされた Module Mirror, Module Index, Module Checksum Database についてまとめていきたいと思います。

Module Mirror( https://proxy.golang.org

Module Mirror は Google から提供される高速かつ高信頼性な Module5 のキャッシュプロキシーです。まだキャッシュされていない Module が Module Mirror にリクエストされた際には、公開されているオリジンサーバーから Module を取得してキャッシュしておいてくれる形です。

この Module Mirror を利用することで Module を高速にダウンロードできたり、GitHub などのオリジンサーバーがダウンしていた場合や URL が変更されてしまった場合でも、指定した Module のダウンロードが可能になります。

それでは Module Mirror の使い方について説明していきます。
Go Modules では Module Proxy(GOPROXY)という概念が導入6 されており、Module の取得をオリジンサーバーでなく任意のサーバーを指定することが可能になっているので、以下のように Module Proxy として Module Mirror を指定することで、ユーザーはその恩恵を受けることができます。

GOPROXY=https://proxy.golang.org

では、実際に Module をオリジンサーバーから取得する場合と Module Mirror から取得する場合の時間を比較してみたいと思います。7

# Go Modules を利用しているプロダクトを Clone してくる
$ git clone https://github.com/spiffe/spire.git
$ cd spire

# Module Mirror を使わずに Module をダウンロードする
$ time GO111MODULE=on go mod download
...
real    2m29.631s
user    2m32.240s
sys 1m5.320s

# Module Mirror を使って Module をダウンロードする
$ GOPROXY=https://proxy.golang.org GO111MODULE=on go mod download
...
real    0m36.504s
user    0m21.410s
sys 0m16.240s

以下の結果となりました。Mirror Module を利用することで Module のダウンロードが高速化されることがわかります。とても早いですね!

あり/なし 所要時間
Mirror Module なし 約2分半
Mirror Module あり 約30秒

Module Checksum Database( https://sum.golang.org

Module を認証するために利用可能な Checksum が格納されているデータベースとなります。8 様々なサーバーで公開されている Module の go.sum が提供されるイメージです。

Module Checksum Database から取得した Checksum と、ダウンロードした Module の Checksum を比較することでコードの信頼性を確認することが可能になります。

少し例をあげると、https://sum.golang.org/latest にリクエストを投げることで、Module Checksum Database のツリーサイズや最新のログのハッシュなどを取得することが出来たり、https://sum.golang.org/lookup/github.com/kubernetes/kubernetes@v1.15.0 のように https://sum.golang.org/lookup/<Module>@<Version> と指定することで、対象 Module の情報を取得することが出来ます。これらを利用して Go コマンドの内部でダウンロードした Module の信頼性確認が行われているのだと思います。

Module Checksum Database の使い方ですが、GOPROXY=https://proxy.golang.org で Module Mirror を利用する場合には、自動的にこの Module Checksum Database が使われる仕様のようです。明示的に設定したい場合には GOSUMDB=sum.golang.org を宣言すれば良いです。

なお、Go 1.12 以前では gosumcheck を使って、手動で Module Checksum Database を使ってのチェックが可能なようなので、興味ある方はお試しください。

go get golang.org/x/mod/gosumcheck
gosumcheck /path/to/go.sum

蛇足ですが、元々は the Go notary という名前だったらしいですが、CNCF Projects の Notary との混同を避けるために現在の命名となったようです。

Module Index( https://index.golang.org

新しい Module のバージョンのフィードを提供するもので https://index.golang.org/index からフィードを確認できます。フィードは年代順にソートされており、各 Module は以下の Key を持った JSON として構成されています。

Key 概要
Path Module 名
Version Module のバージョン
Timestamp Module Mirror( proxy.golang.org )で最初にキャッシュされた時刻

また、以下のパラメータがサポートされています。

パラメータ 概要
since 指定した Timestamp 以降のフィードを取得できる https://index.golang.org/index?since=2019-07-01T17:00:00%2b09:00 (JST で 2019-07-01T17:00:00+09:00 を指定している)
limit 指定したサイズのフィードを取得できる https://index.golang.org/index?limit=10

これを利用することで新しい Module などを発見することが可能になります。godoc.org は今後こちらを参照するようになる?のようなことも記載されておりました。

懸念事項

Module Mirror の個人的な懸念点としては、気をつけて利用しないと Private な Module が Module Mirror にキャッシュされてしまうのでは?ということがあります。なので Private な Module を利用しているプロダクトでの Module Mirror 有効化に少し不安があります。

GOPRIVATE, GONOPROXY, GONOSUMDB 辺りを使えば良いのかな?ぐらいの理解なので、今後調べきれたら追記したいと考えています。

さいごに

今回は Module Mirror, Module Index, Module Checksum Database について紹介しました。現時点では Stable ではないので、不安定性やバグなどがある可能性もありますが、利用する価値はあるのかなと思います。開発されているプロダクトの要件に応じて採用するかどうかをジャッジ頂ければと思います。

Go 1.13 以降の Go コマンドでは、Module Mirror と Module Checksum Database の利用がデフォルトで有効となる( https://github.com/golang/go/commit/f8a5ba2a3880f4782d8250fd26dde2baa3990afa )とのことなので、今後もキャッチアップを続けていきたいと思います。

おしまい。


  1. Go Modules 自体の説明は Go Modulesの概要とGo1.12に含まれるModulesに関する変更 - My External Storage がとてもわかりやすいので、そちらを参照ください。 

  2. go get のオリジナルデザインで重要だったことの1つに、Node の NPM や Java の Maven など中央集権型なコード管理ではなく、誰でも自分のコードを好きなサーバーで公開できて、誰もが好きなサーバーからコードをインポートできるという非中央集権型(分散型)なコード管理というものがあったとのこと。 

  3. Go パッケージの依存関係の分散化の重大な欠点として、公開されている Goパッケージ を見つけることの難しさや、そもそも Goパッケージ の提供が継続される保証がないということが挙げられていました。 

  4. 自分が読み違えて理解している場合もあるので、詳細が気になる方はオリジナルのブログを参照ください。 

  5. 公式ドキュメント では A module is a collection of related Go packages that are versioned together as a single unit. という定義がされています。 

  6. go help goproxy で使い方を参照ください。 

  7. 今回は Go Modules を利用しているプロダクトを Clone する形を取りましたが、単純に go get での比較でも良いと思います。 

  8. 詳細は Proposal: Secure the Public Go Module Ecosystem に記載されています。 

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1