2014-05-13 04:49:05 +04:00
package main
import (
"flag"
"fmt"
"math/rand"
2014-10-24 16:32:49 +04:00
"runtime"
2014-10-28 12:57:29 +03:00
"strings"
2014-05-13 04:49:05 +04:00
"sync"
2014-09-04 10:00:32 +04:00
"sync/atomic"
2014-05-13 04:49:05 +04:00
"time"
2015-05-04 17:42:28 +03:00
"github.com/siddontang/goredis"
2014-05-13 04:49:05 +04:00
)
var ip = flag . String ( "ip" , "127.0.0.1" , "redis/ledis/ssdb server ip" )
2014-07-08 11:31:36 +04:00
var port = flag . Int ( "port" , 6380 , "redis/ledis/ssdb server port" )
2014-05-13 04:49:05 +04:00
var number = flag . Int ( "n" , 1000 , "request number" )
var clients = flag . Int ( "c" , 50 , "number of clients" )
2014-09-04 11:49:51 +04:00
var round = flag . Int ( "r" , 1 , "benchmark round number" )
2014-10-23 09:49:43 +04:00
var valueSize = flag . Int ( "vsize" , 100 , "kv value size" )
2014-10-30 11:48:15 +03:00
var tests = flag . String ( "t" , "set,get,randget,del,lpush,lrange,lpop,hset,hget,hdel,zadd,zincr,zrange,zrevrange,zdel" , "only run the comma separated list of tests" )
2014-05-13 04:49:05 +04:00
var wg sync . WaitGroup
2015-03-11 06:54:02 +03:00
var client * goredis . Client
2014-05-13 04:49:05 +04:00
var loop int = 0
2015-03-11 06:54:02 +03:00
func waitBench ( c * goredis . PoolConn , cmd string , args ... interface { } ) {
2014-10-28 18:23:30 +03:00
_ , err := c . Do ( strings . ToUpper ( cmd ) , args ... )
2014-09-04 13:51:43 +04:00
if err != nil {
2014-10-28 18:23:30 +03:00
fmt . Printf ( "do %s error %s\n" , cmd , err . Error ( ) )
2014-05-13 04:49:05 +04:00
}
2014-10-29 07:32:57 +03:00
2014-05-13 04:49:05 +04:00
}
2015-03-11 06:54:02 +03:00
func bench ( cmd string , f func ( c * goredis . PoolConn ) ) {
2014-05-13 04:49:05 +04:00
wg . Add ( * clients )
2014-10-24 09:01:13 +04:00
t1 := time . Now ( )
2014-05-13 04:49:05 +04:00
for i := 0 ; i < * clients ; i ++ {
2014-09-04 13:51:43 +04:00
go func ( ) {
2015-03-02 12:12:55 +03:00
c , _ := client . Get ( )
2014-10-24 12:39:06 +04:00
for j := 0 ; j < loop ; j ++ {
2014-10-29 07:32:57 +03:00
f ( c )
2014-09-04 13:51:43 +04:00
}
2014-10-29 07:32:57 +03:00
c . Close ( )
2014-09-04 13:51:43 +04:00
wg . Done ( )
} ( )
2014-05-13 04:49:05 +04:00
}
wg . Wait ( )
2014-10-24 09:01:13 +04:00
t2 := time . Now ( )
2014-05-13 04:49:05 +04:00
2014-10-28 12:57:29 +03:00
d := t2 . Sub ( t1 )
fmt . Printf ( "%s: %s %0.3f micros/op, %0.2fop/s\n" ,
cmd ,
d . String ( ) ,
float64 ( d . Nanoseconds ( ) / 1e3 ) / float64 ( * number ) ,
float64 ( * number ) / d . Seconds ( ) )
2014-05-13 04:49:05 +04:00
}
2014-09-04 10:00:32 +04:00
var kvSetBase int64 = 0
var kvGetBase int64 = 0
var kvIncrBase int64 = 0
var kvDelBase int64 = 0
2014-05-13 04:49:05 +04:00
func benchSet ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-23 09:49:43 +04:00
value := make ( [ ] byte , * valueSize )
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & kvSetBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "SET" , n , value )
2014-05-13 04:49:05 +04:00
}
bench ( "set" , f )
}
func benchGet ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & kvGetBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "GET" , n )
2014-09-04 10:00:32 +04:00
}
bench ( "get" , f )
}
func benchRandGet ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-28 18:23:30 +03:00
n := rand . Int ( ) % * number
2014-10-29 07:32:57 +03:00
waitBench ( c , "GET" , n )
2014-05-13 04:49:05 +04:00
}
2014-09-04 13:17:47 +04:00
bench ( "randget" , f )
2014-05-13 04:49:05 +04:00
}
2014-09-04 10:00:32 +04:00
func benchDel ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & kvDelBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "DEL" , n )
2014-09-04 10:00:32 +04:00
}
bench ( "del" , f )
}
2014-05-13 04:49:05 +04:00
func benchPushList ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-23 09:49:43 +04:00
value := make ( [ ] byte , 100 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "RPUSH" , "mytestlist" , value )
2014-05-13 04:49:05 +04:00
}
bench ( "rpush" , f )
}
func benchRangeList10 ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "LRANGE" , "mytestlist" , 0 , 10 )
2014-05-13 04:49:05 +04:00
}
2014-09-04 13:17:47 +04:00
bench ( "lrange10" , f )
2014-05-13 04:49:05 +04:00
}
func benchRangeList50 ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "LRANGE" , "mytestlist" , 0 , 50 )
2014-05-13 04:49:05 +04:00
}
2014-09-04 13:17:47 +04:00
bench ( "lrange50" , f )
2014-05-13 04:49:05 +04:00
}
func benchRangeList100 ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "LRANGE" , "mytestlist" , 0 , 100 )
2014-05-13 04:49:05 +04:00
}
2014-09-04 13:17:47 +04:00
bench ( "lrange100" , f )
2014-05-13 04:49:05 +04:00
}
func benchPopList ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "LPOP" , "mytestlist" )
2014-05-13 04:49:05 +04:00
}
bench ( "lpop" , f )
}
2014-09-04 10:00:32 +04:00
var hashSetBase int64 = 0
var hashIncrBase int64 = 0
var hashGetBase int64 = 0
var hashDelBase int64 = 0
2014-05-13 04:49:05 +04:00
func benchHset ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 11:49:51 +04:00
value := make ( [ ] byte , 100 )
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & hashSetBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "HSET" , "myhashkey" , n , value )
2014-05-13 04:49:05 +04:00
}
bench ( "hset" , f )
}
func benchHGet ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & hashGetBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "HGET" , "myhashkey" , n )
2014-09-04 10:00:32 +04:00
}
bench ( "hget" , f )
}
func benchHRandGet ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-28 18:23:30 +03:00
n := rand . Int ( ) % * number
2014-10-29 07:32:57 +03:00
waitBench ( c , "HGET" , "myhashkey" , n )
2014-05-13 04:49:05 +04:00
}
2014-09-04 13:17:47 +04:00
bench ( "hrandget" , f )
2014-05-13 04:49:05 +04:00
}
func benchHDel ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & hashDelBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "HDEL" , "myhashkey" , n )
2014-05-13 04:49:05 +04:00
}
bench ( "hdel" , f )
}
2014-09-04 10:00:32 +04:00
var zsetAddBase int64 = 0
var zsetDelBase int64 = 0
var zsetIncrBase int64 = 0
2014-05-13 04:49:05 +04:00
func benchZAdd ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 11:49:51 +04:00
member := make ( [ ] byte , 16 )
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & zsetAddBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZADD" , "myzsetkey" , n , member )
2014-05-13 04:49:05 +04:00
}
bench ( "zadd" , f )
}
func benchZDel ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & zsetDelBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZREM" , "myzsetkey" , n )
2014-05-13 04:49:05 +04:00
}
bench ( "zrem" , f )
}
func benchZIncr ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-09-04 10:00:32 +04:00
n := atomic . AddInt64 ( & zsetIncrBase , 1 )
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZINCRBY" , "myzsetkey" , 1 , n )
2014-05-13 04:49:05 +04:00
}
bench ( "zincrby" , f )
}
func benchZRangeByScore ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZRANGEBYSCORE" , "myzsetkey" , 0 , rand . Int ( ) , "withscores" , "limit" , rand . Int ( ) % 100 , 100 )
2014-05-13 04:49:05 +04:00
}
bench ( "zrangebyscore" , f )
}
func benchZRangeByRank ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZRANGE" , "myzsetkey" , 0 , rand . Int ( ) % 100 )
2014-05-13 04:49:05 +04:00
}
bench ( "zrange" , f )
}
func benchZRevRangeByScore ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZREVRANGEBYSCORE" , "myzsetkey" , 0 , rand . Int ( ) , "withscores" , "limit" , rand . Int ( ) % 100 , 100 )
2014-05-13 04:49:05 +04:00
}
bench ( "zrevrangebyscore" , f )
}
func benchZRevRangeByRank ( ) {
2015-03-11 06:54:02 +03:00
f := func ( c * goredis . PoolConn ) {
2014-10-29 07:32:57 +03:00
waitBench ( c , "ZREVRANGE" , "myzsetkey" , 0 , rand . Int ( ) % 100 )
2014-05-13 04:49:05 +04:00
}
bench ( "zrevrange" , f )
}
func main ( ) {
2014-10-24 16:32:49 +04:00
runtime . GOMAXPROCS ( runtime . NumCPU ( ) )
2014-05-13 04:49:05 +04:00
flag . Parse ( )
if * number <= 0 {
panic ( "invalid number" )
return
}
if * clients <= 0 || * number < * clients {
panic ( "invalid client number" )
return
}
loop = * number / * clients
addr := fmt . Sprintf ( "%s:%d" , * ip , * port )
2015-03-11 06:54:02 +03:00
client = goredis . NewClient ( addr , "" )
client . SetReadBufferSize ( 10240 )
client . SetWriteBufferSize ( 10240 )
client . SetMaxIdleConns ( 16 )
2014-05-13 04:49:05 +04:00
2014-10-29 07:32:57 +03:00
for i := 0 ; i < * clients ; i ++ {
2015-03-02 12:12:55 +03:00
c , _ := client . Get ( )
2014-10-29 07:32:57 +03:00
c . Close ( )
}
2014-09-04 11:49:51 +04:00
if * round <= 0 {
* round = 1
2014-09-04 10:00:32 +04:00
}
2014-10-28 12:57:29 +03:00
ts := strings . Split ( * tests , "," )
2014-09-04 11:49:51 +04:00
for i := 0 ; i < * round ; i ++ {
2014-10-30 11:48:15 +03:00
for _ , s := range ts {
switch strings . ToLower ( s ) {
case "set" :
benchSet ( )
case "get" :
benchGet ( )
case "randget" :
benchRandGet ( )
case "del" :
benchDel ( )
case "lpush" :
benchPushList ( )
case "lrange" :
benchRangeList10 ( )
benchRangeList50 ( )
benchRangeList100 ( )
case "lpop" :
benchPopList ( )
case "hset" :
benchHset ( )
case "hget" :
benchHGet ( )
benchHRandGet ( )
case "hdel" :
benchHDel ( )
case "zadd" :
benchZAdd ( )
case "zincr" :
benchZIncr ( )
case "zrange" :
benchZRangeByRank ( )
benchZRangeByScore ( )
case "zrevrange" :
//rev is too slow in leveldb, rocksdb or other
//maybe disable for huge data benchmark
benchZRevRangeByRank ( )
benchZRevRangeByScore ( )
case "zdel" :
benchZDel ( )
}
2014-10-08 11:19:50 +04:00
}
2014-09-04 11:49:51 +04:00
println ( "" )
}
2014-05-13 04:49:05 +04:00
}