让我们来观察一下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)
}
}
}