前のページ
Featured image of post go で redis を使う

go で redis を使う

go で redis を使うときは、 go-redis や、 redigo があります。 Redis の 公式サイト でも紹介されています。

今回は軽く go-redis を使って redis を扱ってみます。

go-redis install

go get github.com/go-redis/redis/v8

最新の version は 公式 をみてください。今回は執筆時点で最新の v8 をインストールします。

go-redis で redis client を生成します。

redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "",
    DB:       0,
})

DB というオプションは redis における DB の番号です。デフォルトで、 0 ~ 15 の 16個分の番号を使うことができます。今回は何も考えずに 0 を使います。

set

redis client を作成したら早速 kvs に値をセットしてみましょう。

func setKey(ctx context.Context) error {
	if err := rClient.Set(ctx, "key", "value", 10*time.Second).Err(); err != nil {
		return err
	}
	return nil
}

value は interface{} でセットすることができます。

get

先ほどセットした key から値を取得してみましょう。とっても簡単ですね、これだけです。

func getKey(ctx context.Context) (string, error) {
	res, err := rClient.Get(ctx, "key").Result()
    if err != nil {
        return "", err
    }
	return res, nil
}

value は string で取得するので、もし構造体にマッピングする場合には json.Unmarshal する必要があります。

サンプルコード

今回はシンプルなコードで cache の際のレスポンス速度を体感できるようなサンプルコードを用意しました。

package main

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
)

var rClient *redis.Client

func init() {
	rClient = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})
}

func main() {
	e := gin.New()
	e.GET("", getKey)

	e.Run("localhost:8080")
}

func getKey(c *gin.Context) {
	ctx := c.Request.Context()
	res, err := getCachedKey(ctx, "key")
	if err != nil {
		c.JSON(http.StatusInternalServerError, err)
		return
	}
	c.JSON(http.StatusOK, res)
}

func getCachedKey(ctx context.Context, key string) (string, error) {
	res, err := rClient.Get(ctx, key).Result()
	switch err {
	case nil:
		break
	case redis.Nil:
		if err := setKey(ctx); err != nil {
			return "", err
		}
	default:
		return "", err
	}
	return res, nil
}

func setKey(ctx context.Context) error {
	sum := 0
	for i := 0; i < 3; i++ {
		time.Sleep(100 * time.Millisecond)
		sum += i
	}
	value := fmt.Sprintf("value: %d", sum)
	if err := rClient.Set(ctx, "key", value, 10*time.Second).Err(); err != nil {
		return err
	}
	return nil
}

上記のコードで、 curl localhost:8080 を叩くと cache されていない状態で、 70ms ほどかかりますが、一度叩いてから 10sec 経ってcache が clear されるまでは 10ms 以下でレスポンスが帰ってくると思います。

まとめ

redis の関数( Get()Set() )を wrap させることで汎用的に使いやすくすることができます。また構造体のmarshal / unmarshal も設定することでより使い勝手が良くなります。

redis とりあえず使ってみたい場合はぜひコピペでも良いので、感触を試してみるというのはどうでしょうか。

このページでは、Google Analyticsを利用しています。