LoginSignup
7
3

More than 3 years have passed since last update.

CloudRunでRedis(Memorystore)を利用する

Posted at

この記事は、Google Cloud Platform(GCP)のサービスであるCloudRunでRedisを利用するための方法をまとめたものです。

CloudRundもサーバレスVPCアクセスが利用可能になったので、CloudRunからMemorystore(Redis)を利用することが可能になっています。
CluodRunでできることがどんどん増えていくのは嬉しいですね。

ポイント

  • フルマネージドなインメモリサービスであるMemorystore(Redis,Memcached)を利用する
  • Memorystoreを利用するにはプライベートアドレスでの接続が必要
  • GAEやCloudRunから接続する場合はサーバーレスVPCアクセスを利用する
    ※GAEやCloudRunはマネージドサービスなのでプライベートアドレスが付与されない

手順

  1. サーバーレスVPCを作成
  2. MemoryStoreを作成
  3. CloudRunを作成

1. サーバーレスVPCを作成

CloudRunからアクセスするためのネットワークを作成します。

GCPコンソールから
VPCネットワーク > サーバーレスVPCアクセス
に移動し、コネクタを作成
(初回はAPIを有効化する必要あり)

例えば下記のように設定します。

スクリーンショット 2020-06-30 12.49.43.png

2. Memorystore(Redis)を作成

次に、Memorystore(Redis)を下記の点に注意して作成します。

  • ロケーションを 1.で作成したコネクタと同じリージョンにする
    (今回はasia-northeast1)

  • ネットワークを1.で作成したコネクタと同じネットワークにする
    (今回はdefault)

これらを設定することで 1.のコネクタを通したVPCアクセスが可能になります。

3. CloudRunを作成

最後に、CloudRunにソースコードをデプロイします。

変数設定にRedisのIPアドレス、ポート番号を指定する

2.で作成したMemorystoreのIPアドレス、ポート番号を環境変数に下記のように設定します。

スクリーンショット 2020-06-30 12.45.50.png

接続設定に作成したサーバーレスVPCコネクタを指定する

CloudRunが接続するコネクタを下記の画像のように設定します。

スクリーンショット 2020-06-30 12.39.01.png

サンプルコード

サイト訪問によるカウントアップ

main.go
// Command redis is a basic app that connects to a managed Redis instance.
package main

import (
    "fmt"
    "log"
    "net/http"
    "os"

    "github.com/gomodule/redigo/redis"
)

var redisPool *redis.Pool

func incrementHandler(w http.ResponseWriter, r *http.Request) {
    conn := redisPool.Get()
    defer conn.Close()

    counter, err := redis.Int(conn.Do("INCR", "visits"))
    if err != nil {
        http.Error(w, "Error incrementing visitor counter", http.StatusInternalServerError)
        return
    }
    fmt.Fprintf(w, "Visitor number: %d", counter)
}

func main() {
    redisHost := os.Getenv("REDISHOST")
    redisPort := os.Getenv("REDISPORT")
    redisAddr := fmt.Sprintf("%s:%s", redisHost, redisPort)

    const maxConnections = 10
    redisPool = redis.NewPool(func() (redis.Conn, error) {
        return redis.Dial("tcp", redisAddr)
    }, maxConnections)

    http.HandleFunc("/", incrementHandler)

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
        log.Fatal(err)
    }
}

Dockerfileはかなり適当...

FROM golang:1.13
RUN mkdir -p /app
WORKDIR /app
COPY . /app
RUN go build /app/main.go
ENTRYPOINT ["/app/main"]

ここまでの設定ができていれば、リロードするごとに数値がカウントアップされるサイトがデプロイされていると思います。

参考サイト

GAEからサーバレスVPCへの接続
https://cloud.google.com/appengine/docs/standard/python/connecting-vpc?hl=ja#creating_a_connector

GAE/GoでRedisへ接続する
https://cloud.google.com/appengine/docs/standard/go/using-memorystore?hl=ja

7
3
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
7
3