让我们来观察一下GCP Memorystore的性能
Memorystore是什么?
- 
- memorystoreはGCPのredisマネージドサービスです
 
- 
- BasicとStandardの2つのサービスを提供しています。BasicはHAがない構成でStandardはHA(zone replicationとautomatic failover)構成になっています
 
- 
- 価格はデータ容量ベースで決まります
 
- 現在のredisのバージョンは3.2です
功能
工作负载
- 
- 1KBのデータ100万件をmemorystoreに格納します
 
- 
- データのkey値はstringで1 – 1000000の値が入ります
 
- 
- 各クライアントは1 – 1000000のkey値をランダムに選択してgetを行います
 
- クライアント数を増加させていきgetのレイテンシを測定します
记忆库的设定
- 
- インスタンスの容量 5GB
 
- 
- ネットワークスループット 375MB/秒
 
- redisはデフォルト設定です
最終的結果
クライアント数平均レイテンシ(μs)最大レイテンシ(μs)135063810390918505078171001,2709,5302002,8709,8304006,62025,25360010,46230,40080014,70825,786
- 
- redisの性能を本格的に見たのは始めてたのですが、他のディスクベースのNoSQL(HBaseとかCassandraとか)に比べると安定的に早い性能が出てる感じですね
 
- 800同時接続でも数十ミリ秒のレイテンシなので、ほとんどのシステムで十分と言える性能ではないでしょうか
测量程序
- 
- 参考に測定プログラムを載せておきます。GOで書かれてます。
 
- 
- host,portは適宜書き換えてください
 
- オプションは–threadでスレッド数(クライアント数)を指定、–loadでmemorystoreに測定データをロードするかどうかとなります
package main
import (
    "flag"
    "fmt"
    "math/rand"
    "os"
    "sync"
    "time"
    "github.com/gomodule/redigo/redis"
)
type Result struct {
    count int
    total int64
    max   int64
}
var rChan = make(chan Result, 10000)
var wg = new(sync.WaitGroup)
const HOST = "10.0.1.4"
const PORT = "6379"
const KEYS = 1000000
func main() {
    for i, v := range os.Args {
        fmt.Printf("args[%d] -> %s\n", i, v)
    }
    t := flag.Int("thread", 1, "thread numbers")
    p := flag.Bool("load", false, "initial load")
    flag.Parse()
    if *p {
        load()
    }
    for i := 0; i < *t; i++ {
        wg.Add(1)
        go perf()
    }
    wg.Wait()
    close(rChan)
    count := 0
    var total, max int64 = 0, 0
    for r := range rChan {
        count = count + r.count
        total = total + r.total
        if max < r.max {
            max = r.max
        }
    }
    fmt.Printf("count = %d\n", count)
    fmt.Printf("total = %d\n", total)
    fmt.Printf("avg = %f\n", float64(total)/float64(count))
    fmt.Printf("max = %d\n", max)
}
func perf() {
    redisAddr := fmt.Sprintf("%s:%s", HOST, PORT)
    fmt.Printf("redis addr: %s\n", redisAddr)
    const LOOP = 10000
    conn, err := redis.Dial("tcp", redisAddr)
    if err != nil {
        panic(err)
    }
    var start, end time.Time
    var total, max int64 = 0, 0
    for i := 0; i < LOOP; i++ {
        rand.Seed(time.Now().UnixNano())
        start = time.Now()
        r, err := redis.String(conn.Do("GET", string(rand.Intn(KEYS))))
        end = time.Now()
        if err != nil {
            panic(err)
        }
        if i%1000 == 0 {
            fmt.Printf("count: %d, out: %s\n", i, r)
        }
        t := end.Sub(start).Nanoseconds()
        total = total + t
        if max < t {
            max = t
        }
    }
    var result Result
    result.count = LOOP
    result.max = max
    result.total = total
    rChan <- result
    defer wg.Done()
}
func load() {
    const base = "d"
    const length = 1000
    var data string = ""
    for i := 0; i < length; i++ {
        data = data + base
    }
    redisAddr := fmt.Sprintf("%s:%s", HOST, PORT)
    fmt.Printf("redis addr: %s\n", redisAddr)
    conn, err := redis.Dial("tcp", redisAddr)
    if err != nil {
        panic(err)
    }
    for i := 0; i < KEYS; i++ {
        _, err := redis.String(conn.Do("SET", string(i), data))
        if err != nil {
            panic(err)
        }
    }
}
 
    