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

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

GAE/goの東京リージョンからServerless VPC Access経由でMemorystoreへのアクセスをベンチマークしてみる

f:id:chidakiyo:20191211202210j:plain

つい先日、東京リージョンにも Serverless VPC Access がやってきたので、GAE/SEから Memorystore が利用できるようになりました。
Memorystoreは内部的にはRedisで、今までのGAE/SE 1st-genと呼ばれる環境ではmemcacheが提供されていましたが、2nd-genからはmemcacheが利用できないためMemorystoreを利用する必要がありました。

念願のMemorystoreが利用できるようになったのと、先日の こちらベンチマークを利用してGAE/GO環境からMemorystoreへのパフォーマンスを測定してみようと思います。

環境

  • GAE/go 1.13
  • インスタンスなどはデフォルトのまま
  • VPCは Min throughput: 200 Mbps、 Min throughput: 1000
  • リージョンはすべて東京

条件

  • redigo, go-redisの両方をテストしてみます。
  • redis の SET/GET の API 両方をベンチマークします

コード

以下のような感じです。

redigo

func put() testing.BenchmarkResult {

    conn := RedisPool.Get()
    defer conn.Close()

    result := testing.Benchmark(func(b *testing.B) {
        b.ResetTimer()
        for i := 1; i <= b.N; i++ {
            _, err := conn.Do("SET", key, value)
            if err != nil {
                b.Fatal(err)
            }
        }
    })
    return result
}

func get() testing.BenchmarkResult {
    conn := RedisPool.Get()
    defer conn.Close()

    result := testing.Benchmark(func(b *testing.B) {
        b.ResetTimer()
        for i := 1; i <= b.N; i++ {
            _, err := redis.String(conn.Do("GET", key))
            if err != nil {
                b.Fatal(err)
            }
        }
    })
    return result
}

go-Redis

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
}

ベンチマークの実行

httpハンドラ経由で上記のベンチマークを実行し結果を取得します。

redigo

SET : 1383      1026929 ns/op
SET : 1086     1096002 ns/op
SET : 1076     1101032 ns/op

GET : 1237      974203 ns/op
GET : 1045     1134000 ns/op
GET : 952        1242443 ns/op

go-redis

SET : 986      1021182 ns/op
SET : 916        1185606 ns/op
SET : 1047     1066092 ns/op

GET : 1256      979747 ns/op
GET : 994        1145765 ns/op
GET : 1035     1082792 ns/op

事前にテストしたときは 800μsec だったのですが、
今日の計測ではSET/GETともに 1msec 程度のようでした。

まとめ

仕事ではAerospikeなど高速なKVSを使っているので、Redisで1msecだとちょっと遅いな、と感じちゃうところもありますが、GCPにでおまかせで使えると思えばすごく便利かも。

Memcacheが使えなくなってすごく困っていましたが、これならパフォーマンス気にせずガンガン使っていけそうです!

おわり。