寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。 投げ銭は kyash_id : chidakiyo マデ

# Go のテスト並列化してテストが速くなることを改めて確認してみた

f:id:chidakiyo:20200625164918j:plain

Go のテストに並列機能があるので、それで単純に速度アップができるのかという点と、 parallel オプションで並列数操作したらちゃんと反映されるよね。という点を確認した。

早速ソースコード

slow_test.go

func Test_slow1(t *testing.T) {
    time.Sleep(3 * time.Second)
}

func Test_slow2(t *testing.T) {
    time.Sleep(1 * time.Second)
}

func Test_slow3(t *testing.T) {
    time.Sleep(2 * time.Second)
}

fast_test.go

func Test_fast1(t *testing.T) {
    t.Parallel()
    time.Sleep(3 * time.Second)
}

func Test_fast2(t *testing.T) {
    t.Parallel()
    time.Sleep(1 * time.Second)
}

func Test_fast3(t *testing.T) {
    t.Parallel()
    time.Sleep(2 * time.Second)
}

見てわかるように fast の方ではテスト内で Parallel() を呼び出して並列処理を許可している。

早速実行

slow の方を実行する

% go test ./slow_test.go
ok      command-line-arguments  6.276s

6秒ちょい。
3 + 1 + 2 = 6秒なのでだいたい正しい。

fast の方を実行する

% go test ./fast_test.go
ok      command-line-arguments  3.729s

3.7秒。
3並列で実行され、一番遅い3秒のテスト時間+αという感じだろうか。

fast を並列数 1 で実行してみる

% go test -parallel 1 ./fast_test.go
ok      command-line-arguments  6.502s

6.5秒。 期待通り、並列化していない slow の結果とだいたい近い値になった。
Parallel() を呼び出していないものよりちょっと遅いのは Parallel() 呼び出しのオーバーヘッドがそこそこあるのだろうか。

fast を並列数 2 で実行してみる

% go test -parallel 2 ./fast_test.go
ok      command-line-arguments  3.342s

3.3秒。
3 : (1 + 2) で3秒少々で終わったという感じだろうか。

slow を並列数 3 で実行してみる

% go test -parallel 3 ./slow_test.go
ok      command-line-arguments  6.350s

6.3秒。
もちろんそうなるよね。という感じ。

まとめ

Go のテストは実行順序や、同時実行などを考慮しなくて良いテストに関しては Parallel() を実行し、並列化したほうがパフォーマンスが出る。
確認で使った環境は go1.14.3 で、このバージョンであれば、 go test コマンドに特に並列数など渡さなくてもテスト側で Parallel() を読んでいれば必要な数だけ並列化されそう。(もしくはPCのCore数に応じて?)

GitHub Actionsなどは時間課金なのでテスト高速化して削減できそう。

ではでは。

キャッシュレス関連用語集 [経済産業省]

f:id:chidakiyo:20200625113614j:plain

キャッシュレス関連用語集 が公開されていて良さそうな感じだったので。

目次はこんな感じ。
f:id:chidakiyo:20200625113305p:plain f:id:chidakiyo:20200625113448p:plain f:id:chidakiyo:20200625113316p:plain f:id:chidakiyo:20200625113338p:plain f:id:chidakiyo:20200625113349p:plain f:id:chidakiyo:20200625113406p:plain

リンク先はPDFです

https://www.meti.go.jp/policy/mono_info_service/cashless/image_pdf_movie/cashless_glossary_R1_06.pdf

Cloud Run と GitHub を連携して、GitHub にコードをプッシュするだけでファイルをインターネットに公開できるように設定する

f:id:chidakiyo:20200624111932j:plain

Cloud Run が GitHub と接続設定をするだけで、 GitHub 上に push したコードをデプロイ出来る仕組みが簡単に作れるので、静的ファイルを簡単にデプロイ出来るミニマムな方法になります。

GCSで公開やFirebase Hostingなど他にも公開するシンプルな方法はありますが、 GCP や Firebase など GitHub 以外の存在を隠蔽して static file を公開する仕組みを作りたい場合(社内の非エンジニアなどにも対応してほしい場合)などに利用できるかと思います。
カスタムドメイン化やSSL化も容易だし。

GitHubにコードを配置する。

こちら がサンプルになります。
初期設定時に必要なものとしては、 Dockerfile, default.conf は仕組みとして必要です。
これがなぜ必要なのか理解できない人は Docker で nginx コンテナを利用してコンテンツを公開する方法などを検索して学ぶと良いと思います。
仕組みが理解できていれば、 node でも go でもこのパターンを応用して公開できます。

話が脱線しましたが、このリポジトリで外部に公開したいファイルは index.html になります。
中身は超手抜きで以下のようなもの(Hello!と大きく表示されるだけ)です。

<h1>Hello!!</h1>

上記のようなイメージで GitHubリポジトリを用意します。

GCPにプロジェクトを作成する

すでに作成しているものがあれば Cloud Run を有効化し、
未作成の場合にはプロジェクトの作成の後、Cloud Run の有効化を行います。
(細かい手順は省略します)

Run と GitHub を統合する

まずは GCP の Cloud Run の画面を表示します

f:id:chidakiyo:20200624112012p:plain

まずは、何もない状態だと思いますので、上段の 「CREATE SERVICE」ボタンを押します。

f:id:chidakiyo:20200624112025p:plain

Service settings の項目は、自分が利用したいリージョン、サービス名を入力します。
Authenticationは外部に公開するのであれば Allow unauthenticatec invocations を選択しましょう

入力が済んだら 「NEXT」ボタンを押します。

f:id:chidakiyo:20200624112046p:plain

ここからがポイント。

Configure the service's first revision の設定項目では、
Continuously deploy new revisions from a source repository を選択します。

選択すると表示が狭まるので、「SET UP CLOUD BUILD」ボタンを押します。

f:id:chidakiyo:20200624112058p:plain

リポジトリGitHub/Bitbucket が選択できます。
今回は GitHub を選択しましょう。

尚、この際に、 Cloud Source Repositories API , Cloud Build API の有効化が必要になります。
それに伴い billing の有効化も必要になります。リンクから遷移して有効化しておきましょう。

有効化が済むと、 「Authenticate」のリンクが表示されます。
これは GCP から GitHub に接続するための認証になりますので実行しておきます。

認証が完了すると、リポジトリの選択ができるようになります。
以下のように選択し、有効な状態になっていることを確認しましょう(ちゃんと青くなる)

確認できたら 「NEXT」を実行します。

Build 設定を行う

f:id:chidakiyo:20200624112111p:plain

こちらのように Build 設定が表示されます。
任意のブランチを選択し、今回は Dockerfile を利用しますので、 Source location は /Dockerfile を利用します。

設定が完了したら 「SAVE」 ボタンを実行します。

Cloud Run のサービスを作成する

入力がすべて完了したら、 一番下段の 「CREATE」ボタンを実行します。

尚、デプロイの際の細かいパラメータを変更したい場合には、 ADVANCED SETTINGS を展開することで設定の変更が可能です。
メモリの量や、CPUのコア数などの指定が行なえます。

CREATE ボタンを実行すると Cloud Run のサービス詳細画面に遷移し、サービスのデプロイ状況が確認できます。

変更の際にデプロイされるか確認する

GitHub で管理しているコードを変更して master に push してみます。

f:id:chidakiyo:20200624112131p:plain

このような感じでデプロイが行われました。

f:id:chidakiyo:20200624112144p:plain

コンテンツも表示されました。

めでたし、めでたし。

今更読んだ : 監視 入門 ~ マイクロサービス時代の監視設計

f:id:chidakiyo:20200615143836j:plain

Songmu さんの書いた 2019 年の Rancher Meetup Tokyo の記事

監視周りの基本的なエッセンスがまとまっていて、 要点を手っ取り早く吸収したい人にはおすすめ。

junkyard.song.mu

anyenv のインストールから nodenv のインストールまで

f:id:chidakiyo:20200518180313j:plain

anyenv のインストールから nodenv のインストールまで

Mac が新しくなったので node をインストールしようと思い、以前 nodebrew を使っていたので GitHub を見に行ったら開発はいまいち活発じゃなさそう。
なので、ちょっと調べてみたら nodenv の方が活発そうでしかも anyenv を経由して xxxenv もインストールできるというので面白そうなのでやってみた。

anyenv のインストール

homebrew が入っていれば brew コマンドでインストールが可能。便利。

brew install anyenv

ひとまず普通に brew の設定ができていればインストールは問題なく完了するはず。

つぎに anyenv の初期化を行う

anyenv install --init

で初期化が完了する。

nodenv のインストール

anyenv 経由で nodenv をインストールする

anyenv install nodenv

シェルの再起動

exec $SHELL -l

node のインストール

node のインストールまではこの記事で書かないつもりでしたがおまけ。

インストールできるバージョンを確認

nodenv install -l

現状新しそうな 13.14.0 をインストールしてみる

nodenv install 13.14.0

グローバル設定を行う。(普段使うnodeとして設定する)

nodenv global 13.14.0

node のバージョンを確認する

node -v
v13.14.0

という感じで適用されていればオッケー

ではでは。

Cloud Run で VPC 経由で Memorystore(Redis) に接続確認してみる

f:id:chidakiyo:20200515144527j:plain

待望の機能がBetaですが発表されましたね!

注意 : Cloud Run の VPC 接続は現在(2020/05/15)Betaです。
注意 : 以下、Cloud Runと読んでいるものはすべてフルマネージド版になります。

Cloud Run のようなサービスは Memorystore(Redis) に接続する際、 Serverless VPC Access を利用する必要がありました。
VPC Access が提供されていなかったため Cloud Run から Memorystore への接続が実質行えませんでしたが、Beta で公開されたので早速試してみます。

この内容は主に ( https://cloud.google.com/run/docs/configuring/connecting-vpc ) のドキュメントの内容をベースにしています。

Serverless VPC Access Connector の作成

コネクタを作成します。

注意点として、α版の Cloud Run を利用した場合、Cloud Run のサービスアカウントに Serverless VPC Access ろ利用するための必要な権限がないIAMロールを利用している場合があるようです。
その場合には ( https://cloud.google.com/run/docs/issues#service-account ) こちらから確認できるようです。不安な場合には新しいプロジェクトなり、新しく Cloud Run をデプロイするなりしたほうが良さそうです。

一度も利用していない場合には VPC Access API の有効化が必要です。以下のコマンドで有効化します

gcloud services enable vpcaccess.googleapis.com

以下のコマンドでコネクタを作成します
一度作成すればそのコネクタは Cloud Run 側で再利用が可能です。

gcloud compute networks vpc-access connectors create ${CONNECTOR_NAME} \
--network ${VPC_NETWORK} \
--region ${REGION} \
--range ${IP_RANGE}
--project ${PROJECT_ID}

特にわかりづらそうな項目を解説すると
VPC_NETWORK : コネクタを接続するVPCネットワークで、Memorystore を作成する際に作った VPC 名を記述します。
IP_RANGE : 予約されていない CIDR(/28) の internal な IP レンジを指定します。VPC 内の IP アドレスと重複しないように指定する必要があります。

コネクタの READY 状態を確認する場合には以下のコマンドを実行します。

gcloud compute networks vpc-access connectors describe ${CONNECTOR_NAME} --region ${REGION}

Cloud Run に Serverless VPC Connector を適用する

コネクタが作成されていれば以下のようにデプロイコマンドのオプションでコネクタ名を指定すれば良いです。

gcloud beta run deploy ${SERVICE} --image gcr.io/${PROJECT_ID}/${IMAGE} --vpc-connector ${CONNECTOR_NAME}

すでに起動している Cloud Run に適用することもできます。
その場合には以下のようなコマンドをじっこうします。

gcloud beta run services update ${SERVICE} --vpc-connector ${CONNECTOR_NAME}

ざっくりパフォーマンス測定してみる

コードは以下のような雰囲気(w

func put() testing.BenchmarkResult {
    result := testing.Benchmark(func(b *testing.B) {
        b.ResetTimer()
        for i := 1; i <= b.N; i++ {
            cmd := RedisClient.Set(key, value, 0)
            if cmd != nil && cmd.Err() != nil {
                b.Fatal(cmd.Err())
            }
        }
    })
    return result
}

func get() testing.BenchmarkResult {
    result := testing.Benchmark(func(b *testing.B) {
        b.ResetTimer()
        for i := 1; i <= b.N; i++ {
            cmd := RedisClient.Get(key)
            if cmd != nil && cmd.Err() != nil {
                b.Fatal(cmd.Err())
            }
        }
    })
    return result
}

実際の実行結果 3回分
上段が set, 下段が get.

   1748       668063 ns/op
   1815       649694 ns/op
    1940      587431 ns/op
    2076      595448 ns/op
    2008      605562 ns/op
    2024      619581 ns/op

参考まで同様のコードをGAEで動かすと

    1189      971718 ns/op
    1156     1027043 ns/op
    1956      948939 ns/op
    1120      918023 ns/op
    1209      994508 ns/op
    1118      981328 ns/op

こんな感じ。
どうやら少しだけ Run のほうが早そうな気がしますね。

参考

https://cloud.google.com/run/docs/configuring/connecting-vpc https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#creating_a_connector