bench_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. package redis_test
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "strings"
  7. "testing"
  8. "time"
  9. "github.com/go-redis/redis/v7"
  10. )
  11. func benchmarkRedisClient(poolSize int) *redis.Client {
  12. client := redis.NewClient(&redis.Options{
  13. Addr: ":6379",
  14. DialTimeout: time.Second,
  15. ReadTimeout: time.Second,
  16. WriteTimeout: time.Second,
  17. PoolSize: poolSize,
  18. })
  19. if err := client.FlushDB().Err(); err != nil {
  20. panic(err)
  21. }
  22. return client
  23. }
  24. func BenchmarkRedisPing(b *testing.B) {
  25. client := benchmarkRedisClient(10)
  26. defer client.Close()
  27. b.ResetTimer()
  28. b.RunParallel(func(pb *testing.PB) {
  29. for pb.Next() {
  30. if err := client.Ping().Err(); err != nil {
  31. b.Fatal(err)
  32. }
  33. }
  34. })
  35. }
  36. func BenchmarkRedisGetNil(b *testing.B) {
  37. client := benchmarkRedisClient(10)
  38. defer client.Close()
  39. b.ResetTimer()
  40. b.RunParallel(func(pb *testing.PB) {
  41. for pb.Next() {
  42. if err := client.Get("key").Err(); err != redis.Nil {
  43. b.Fatal(err)
  44. }
  45. }
  46. })
  47. }
  48. type setStringBenchmark struct {
  49. poolSize int
  50. valueSize int
  51. }
  52. func (bm setStringBenchmark) String() string {
  53. return fmt.Sprintf("pool=%d value=%d", bm.poolSize, bm.valueSize)
  54. }
  55. func BenchmarkRedisSetString(b *testing.B) {
  56. benchmarks := []setStringBenchmark{
  57. {10, 64},
  58. {10, 1024},
  59. {10, 64 * 1024},
  60. {10, 1024 * 1024},
  61. {10, 10 * 1024 * 1024},
  62. {100, 64},
  63. {100, 1024},
  64. {100, 64 * 1024},
  65. {100, 1024 * 1024},
  66. {100, 10 * 1024 * 1024},
  67. }
  68. for _, bm := range benchmarks {
  69. b.Run(bm.String(), func(b *testing.B) {
  70. client := benchmarkRedisClient(bm.poolSize)
  71. defer client.Close()
  72. value := strings.Repeat("1", bm.valueSize)
  73. b.ResetTimer()
  74. b.RunParallel(func(pb *testing.PB) {
  75. for pb.Next() {
  76. err := client.Set("key", value, 0).Err()
  77. if err != nil {
  78. b.Fatal(err)
  79. }
  80. }
  81. })
  82. })
  83. }
  84. }
  85. func BenchmarkRedisSetGetBytes(b *testing.B) {
  86. client := benchmarkRedisClient(10)
  87. defer client.Close()
  88. value := bytes.Repeat([]byte{'1'}, 10000)
  89. b.ResetTimer()
  90. b.RunParallel(func(pb *testing.PB) {
  91. for pb.Next() {
  92. if err := client.Set("key", value, 0).Err(); err != nil {
  93. b.Fatal(err)
  94. }
  95. got, err := client.Get("key").Bytes()
  96. if err != nil {
  97. b.Fatal(err)
  98. }
  99. if !bytes.Equal(got, value) {
  100. b.Fatalf("got != value")
  101. }
  102. }
  103. })
  104. }
  105. func BenchmarkRedisMGet(b *testing.B) {
  106. client := benchmarkRedisClient(10)
  107. defer client.Close()
  108. if err := client.MSet("key1", "hello1", "key2", "hello2").Err(); err != nil {
  109. b.Fatal(err)
  110. }
  111. b.ResetTimer()
  112. b.RunParallel(func(pb *testing.PB) {
  113. for pb.Next() {
  114. if err := client.MGet("key1", "key2").Err(); err != nil {
  115. b.Fatal(err)
  116. }
  117. }
  118. })
  119. }
  120. func BenchmarkSetExpire(b *testing.B) {
  121. client := benchmarkRedisClient(10)
  122. defer client.Close()
  123. b.ResetTimer()
  124. b.RunParallel(func(pb *testing.PB) {
  125. for pb.Next() {
  126. if err := client.Set("key", "hello", 0).Err(); err != nil {
  127. b.Fatal(err)
  128. }
  129. if err := client.Expire("key", time.Second).Err(); err != nil {
  130. b.Fatal(err)
  131. }
  132. }
  133. })
  134. }
  135. func BenchmarkPipeline(b *testing.B) {
  136. client := benchmarkRedisClient(10)
  137. defer client.Close()
  138. b.ResetTimer()
  139. b.RunParallel(func(pb *testing.PB) {
  140. for pb.Next() {
  141. _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
  142. pipe.Set("key", "hello", 0)
  143. pipe.Expire("key", time.Second)
  144. return nil
  145. })
  146. if err != nil {
  147. b.Fatal(err)
  148. }
  149. }
  150. })
  151. }
  152. func BenchmarkZAdd(b *testing.B) {
  153. client := benchmarkRedisClient(10)
  154. defer client.Close()
  155. b.ResetTimer()
  156. b.RunParallel(func(pb *testing.PB) {
  157. for pb.Next() {
  158. err := client.ZAdd("key", &redis.Z{
  159. Score: float64(1),
  160. Member: "hello",
  161. }).Err()
  162. if err != nil {
  163. b.Fatal(err)
  164. }
  165. }
  166. })
  167. }
  168. var clientSink *redis.Client
  169. func BenchmarkWithContext(b *testing.B) {
  170. rdb := benchmarkRedisClient(10)
  171. defer rdb.Close()
  172. ctx := context.Background()
  173. b.ResetTimer()
  174. b.ReportAllocs()
  175. for i := 0; i < b.N; i++ {
  176. clientSink = rdb.WithContext(ctx)
  177. }
  178. }
  179. var ringSink *redis.Ring
  180. func BenchmarkRingWithContext(b *testing.B) {
  181. rdb := redis.NewRing(&redis.RingOptions{})
  182. defer rdb.Close()
  183. ctx := context.Background()
  184. b.ResetTimer()
  185. b.ReportAllocs()
  186. for i := 0; i < b.N; i++ {
  187. ringSink = rdb.WithContext(ctx)
  188. }
  189. }
  190. //------------------------------------------------------------------------------
  191. func newClusterScenario() *clusterScenario {
  192. return &clusterScenario{
  193. ports: []string{"8220", "8221", "8222", "8223", "8224", "8225"},
  194. nodeIDs: make([]string, 6),
  195. processes: make(map[string]*redisProcess, 6),
  196. clients: make(map[string]*redis.Client, 6),
  197. }
  198. }
  199. func BenchmarkClusterPing(b *testing.B) {
  200. if testing.Short() {
  201. b.Skip("skipping in short mode")
  202. }
  203. cluster := newClusterScenario()
  204. if err := startCluster(cluster); err != nil {
  205. b.Fatal(err)
  206. }
  207. defer stopCluster(cluster)
  208. client := cluster.clusterClient(redisClusterOptions())
  209. defer client.Close()
  210. b.ResetTimer()
  211. b.RunParallel(func(pb *testing.PB) {
  212. for pb.Next() {
  213. err := client.Ping().Err()
  214. if err != nil {
  215. b.Fatal(err)
  216. }
  217. }
  218. })
  219. }
  220. func BenchmarkClusterSetString(b *testing.B) {
  221. if testing.Short() {
  222. b.Skip("skipping in short mode")
  223. }
  224. cluster := newClusterScenario()
  225. if err := startCluster(cluster); err != nil {
  226. b.Fatal(err)
  227. }
  228. defer stopCluster(cluster)
  229. client := cluster.clusterClient(redisClusterOptions())
  230. defer client.Close()
  231. value := string(bytes.Repeat([]byte{'1'}, 10000))
  232. b.ResetTimer()
  233. b.RunParallel(func(pb *testing.PB) {
  234. for pb.Next() {
  235. err := client.Set("key", value, 0).Err()
  236. if err != nil {
  237. b.Fatal(err)
  238. }
  239. }
  240. })
  241. }
  242. func BenchmarkClusterReloadState(b *testing.B) {
  243. if testing.Short() {
  244. b.Skip("skipping in short mode")
  245. }
  246. cluster := newClusterScenario()
  247. if err := startCluster(cluster); err != nil {
  248. b.Fatal(err)
  249. }
  250. defer stopCluster(cluster)
  251. client := cluster.clusterClient(redisClusterOptions())
  252. defer client.Close()
  253. b.ResetTimer()
  254. for i := 0; i < b.N; i++ {
  255. err := client.ReloadState()
  256. if err != nil {
  257. b.Fatal(err)
  258. }
  259. }
  260. }
  261. var clusterSink *redis.ClusterClient
  262. func BenchmarkClusterWithContext(b *testing.B) {
  263. rdb := redis.NewClusterClient(&redis.ClusterOptions{})
  264. defer rdb.Close()
  265. ctx := context.Background()
  266. b.ResetTimer()
  267. b.ReportAllocs()
  268. for i := 0; i < b.N; i++ {
  269. clusterSink = rdb.WithContext(ctx)
  270. }
  271. }