Skip to content

Instantly share code, notes, and snippets.

@nicksherron
Created June 30, 2021 06:23
Show Gist options
  • Select an option

  • Save nicksherron/cc66aa9cffa3e3f59e14529b63d67466 to your computer and use it in GitHub Desktop.

Select an option

Save nicksherron/cc66aa9cffa3e3f59e14529b63d67466 to your computer and use it in GitHub Desktop.
package redis_test
import (
"context"
"fmt"
"os"
"strings"
"testing"
"time"
"github.com/couchbase/gocb/v2"
gojcbmock "github.com/couchbase/gocbcore/v9/jcbmock"
"github.com/go-redis/redis/v8"
)
var payload = []byte(`{"status":200,"errors":null,"num_results":1,"result":{"id":1115,"created_at":"2021-06-22T14:44:23.708Z","created_by":"","updated_at":"2021-06-22T14:44:23.708Z","updated_by":"","fulfillment_provider_id":35166,"quantity":566182,"sku_id":747095,"tracking":"lots","warehouse_id":204396,"allocated":-572353,"not_available":73445,"on_hand":366175,"cost":"814.27","date_available":"1922-07-27T14:25:56.949Z","expiration_date":"1974-02-20T00:01:15.785Z","lots":{"InventoryID":1115,"lot_num":639101},"stock_commitments":[{"id":3638,"created_at":"2021-06-22T14:44:23.71Z","created_by":"","updated_at":"2021-06-22T14:44:23.71Z","updated_by":"","InventoryID":1115,"active":true,"expiration":"1962-01-08T06:04:23.894Z","lot_id":"206686","policy":"VyzflXGl","replenish":false,"total_quantity":0,"warehouse_id":0},{"id":3639,"created_at":"2021-06-22T14:44:23.71Z","created_by":"","updated_at":"2021-06-22T14:44:23.71Z","updated_by":"","InventoryID":1115,"active":true,"expiration":"1991-11-25T18:37:25.369Z","lot_id":"281413","policy":"lefkdMx","replenish":false,"total_quantity":0,"warehouse_id":0},{"id":3640,"created_at":"2021-06-22T14:44:23.71Z","created_by":"","updated_at":"2021-06-22T14:44:23.71Z","updated_by":"","InventoryID":1115,"active":false,"expiration":"1925-08-06T04:11:17.324Z","lot_id":"298084","policy":"HWicxE","replenish":false,"total_quantity":0,"warehouse_id":0},{"id":3641,"created_at":"2021-06-22T14:44:23.71Z","created_by":"","updated_at":"2021-06-22T14:44:23.71Z","updated_by":"","InventoryID":1115,"active":false,"expiration":"1981-10-07T12:11:36.465Z","lot_id":"341815","policy":"CzgJ","replenish":false,"total_quantity":0,"warehouse_id":0},{"id":3642,"created_at":"2021-06-22T14:44:23.71Z","created_by":"","updated_at":"2021-06-22T14:44:23.71Z","updated_by":"","InventoryID":1115,"active":true,"expiration":"1996-09-16T22:04:58.666Z","lot_id":"652908","policy":"vDMFYACp","replenish":false,"total_quantity":0,"warehouse_id":0}]}}`)
func init() {
fmt.Println(len(payload))
}
const poolSize = 5
func benchmarkCouchbaseBucket() *gocb.Bucket {
mpath := "/Users/nicksherron/go/src/github.com/couchbase/CouchbaseMock/target/CouchbaseMock-1.5.26.jar"
mock, err := gojcbmock.NewMock(mpath, 4, 1, 64, []gojcbmock.BucketSpec{
{Name: "default", Type: gojcbmock.BCouchbase},
}...)
if err != nil {
panic(err.Error())
}
mock.Control(gojcbmock.NewCommand(gojcbmock.CSetCCCP,
map[string]interface{}{"enabled": "true"}))
var addrs []string
for _, mcport := range mock.MemcachedPorts() {
addrs = append(addrs, fmt.Sprintf("127.0.0.1:%d", mcport))
}
fmt.Println(addrs)
connStr := fmt.Sprintf("couchbase://%s", strings.Join(addrs, ","))
fmt.Println(connStr)
// time.Sleep(1 * time.Minute)
cluster, err := gocb.Connect(
connStr,
gocb.ClusterOptions{
Transcoder: gocb.NewRawBinaryTranscoder(),
Username: "Administrator",
Password: "password",
})
if err != nil {
panic(err.Error())
}
bucket := cluster.Bucket("default")
if err := bucket.WaitUntilReady(15*time.Second, nil); err != nil {
panic(err.Error())
}
return bucket
}
func tryUntil(deadline time.Time, interval time.Duration, fn func() bool) bool {
for {
success := fn()
if success {
return true
}
sleepDeadline := time.Now().Add(interval)
if sleepDeadline.After(deadline) {
return false
}
time.Sleep(sleepDeadline.Sub(time.Now()))
}
}
const (
cbHostFromEnv = "ASTUR_COUCHBASE_HOST"
cbUserDefault = "acenda"
cbUserFromEnv = "ASTUR_COUCHBASE_USER"
cbPasswordDefault = "p@ssw0rd"
cbPasswordFromEnv = "ASTUR_COUCHBASE_PASSWORD"
cbBucketDefault = "default"
cbBucketFromEnv = "ASTUR_COUCHBASE_BUCKET"
)
var (
cbUser = cbUserDefault
cbPassword = cbPasswordDefault
cbBucket = cbBucketDefault
DefaultCacheTTL = 60 * time.Second
)
func init() {
if s := os.Getenv(cbUserFromEnv); s != "" {
cbUser = s
}
if s := os.Getenv(cbPasswordFromEnv); s != "" {
cbPassword = s
}
if s := os.Getenv(cbBucketFromEnv); s != "" {
cbBucket = s
}
}
func connectCouchbase() *gocb.Bucket {
cluster, err := gocb.Connect(
"localhost",
gocb.ClusterOptions{
Transcoder: gocb.NewRawBinaryTranscoder(),
Username: cbUser,
Password: cbPassword,
})
if err != nil {
panic(err)
}
bucket := cluster.Bucket(cbBucket)
if err := bucket.WaitUntilReady(5*time.Second, nil); err != nil {
panic(err)
}
return bucket
}
func benchmarkRedisClient(ctx context.Context, poolSize int) *redis.Client {
client := redis.NewClient(&redis.Options{
Addr: ":6379",
DialTimeout: time.Second,
ReadTimeout: time.Second,
WriteTimeout: time.Second,
PoolSize: poolSize,
})
if err := client.FlushDB(ctx).Err(); err != nil {
panic(err)
}
return client
}
func BenchmarkRedisSetNotParallel(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := client.Set(ctx, "key1", payload, 30*time.Second).Err(); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkCouchbaseSetNotParallel(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := collection.Upsert("key1", payload, &gocb.UpsertOptions{Expiry: time.Second * 30}); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkRedisSet(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := client.Set(ctx, "key1", payload, 30*time.Second).Err(); err != nil {
b.Fatal(err)
}
}
})
}
func BenchmarkCouchbaseSet(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if _, err := collection.Upsert("key1", payload, &gocb.UpsertOptions{Expiry: time.Second * 30}); err != nil {
b.Fatal(err)
}
}
})
}
func BenchmarkRedisGetNotParallel(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
if err := client.Set(ctx, "key1", payload, 30*time.Second).Err(); err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := client.Get(ctx, "key1").Err(); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkCouchbaseGetNotParallel(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
collection.Insert("key1", payload, &gocb.InsertOptions{Expiry: time.Second * 30})
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := collection.Get("key1", nil); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkRedisGet(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
if err := client.Set(ctx, "key1", payload, 30*time.Second).Err(); err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := client.Get(ctx, "key1").Err(); err != nil {
b.Fatal(err)
}
}
})
}
func BenchmarkCouchbaseGet(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
collection.Insert("key1", payload, &gocb.InsertOptions{Expiry: time.Second * 30})
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if _, err := collection.Get("key1", nil); err != nil {
b.Fatal(err)
}
}
})
}
func BenchmarkRedisDelNotParallel(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
// we can't check for error because we have to keep an even playing field and coucbase won't allow it
client.Del(ctx, "key1").Err()
//if err := client.Del(ctx, "key1").Err(); err != nil {
// b.Fatal(err)
//}
}
}
func BenchmarkCouchbaseDelNotParallel(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
// couchbase will complain since we already deleted the key
collection.Remove("key1", nil)
}
}
func BenchmarkRedisDel(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
// we can't check for error because we have to keep an even playing field and coucbase won't allow it
client.Del(ctx, "key1").Err()
//if err := client.Del(ctx, "key1").Err(); err != nil {
// b.Fatal(err)
//}
}
})
}
func BenchmarkCouchbaseDel(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
// couchbase will complain since we already deleted the key
collection.Remove("key1", nil)
}
})
}
func BenchmarkRedisExistsNotParallel(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := client.Exists(ctx, "key1").Err(); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkCouchbaseExistsNotParallel(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
for i := 0; i < b.N; i++ {
if _, err := collection.Exists("key1", nil); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkRedisExists(b *testing.B) {
ctx := context.Background()
client := benchmarkRedisClient(ctx, poolSize)
defer client.Close()
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := client.Exists(ctx, "key1").Err(); err != nil {
b.Fatal(err)
}
}
})
}
func BenchmarkCouchbaseExists(b *testing.B) {
bucket := connectCouchbase()
collection := bucket.DefaultCollection()
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(100)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if _, err := collection.Exists("key1", nil); err != nil {
b.Fatal(err)
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment