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

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

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