• 使用Go语言测试Redis性能


    1. 前言

    Redis是一个高性能的键值存储数据库,常用于缓存、队列、排行榜等场景。在实际应用中,我们需要对Redis的性能进行测试,以便了解其在不同场景下的表现。本文将介绍如何使用Go语言测试Redis的性能。

    2. 环境准备

    在开始测试前,我们需要准备以下环境:
    ·Redis服务器
    ·Go语言开发环境
    在本文中,我们将使用Redis单机和Redis集群进行测试。

    3. 测试方案

    我们将使用Go语言编写一个测试脚本,通过多个并发客户端向Redis服务器发送请求,测试其性能表现。测试脚本将支持以下命令行参数:
    -h:Redis服务器的主机名或IP地址,默认为localhost。
    -p:Redis服务器的端口号,默认为6379。
    -n:执行的请求数量,默认为1000。
    -c:并发客户端数量,默认为10。
    -d:写入Redis的数据大小,默认为1024。
    -t:Redis命令类型,支持set和get,默认为set。
    -P:Redis密码,默认为空。
    -D:Redis数据库,默认为0。
    –cluster:是否连接Redis集群,默认为false。
    测试脚本将创建多个并发客户端,每个客户端将执行指定数量的请求,并向Redis服务器发送指定类型的命令。测试脚本将输出测试结果,包括执行请求数量、并发客户端数量、写入数据大小、Redis命令类型、总共用时、平均每秒请求数量等信息。

    4. 测试脚本

    以下是完整的测试脚本代码:

    package main
    
    import (
    	"context"
    	"flag"
    	"fmt"
    	"github.com/go-redis/redis/v8"
    	"log"
    	"os"
    	"strings"
    	"sync"
    	"time"
    )
    
    func main() {
    	ctx := context.Background()
    	logger := log.New(log.Writer(), "", log.LstdFlags)
    	// 解析命令行参数
    	host := flag.String("h", "localhost", "Redis 服务器的主机名或 IP 地址")
    	port := flag.String("p", "6379", "Redis 服务器的端口号")
    	requests := flag.Int("n", 1000, "执行的请求数量")
    	clients := flag.Int("c", 10, "并发客户端数量")
    	dataSize := flag.Int("d", 1024, "写入 Redis 的数据大小")
    	cmdType := flag.String("t", "set", "Redis 命令类型")
    	password := flag.String("P", "", "redis密码")
    	db := flag.Int("D", 0, "数据库")
    	cluster := flag.Bool("cluster", false, "是否连接集群")
    	flag.Parse()
    
    	flag.CommandLine.Usage = func() {
    		fmt.Fprintf(os.Stderr, "Usage: %s [options]\n", os.Args[0])
    		fmt.Fprintf(os.Stderr, "Options:\n")
    		flag.PrintDefaults()
    	}
    	var rdb redis.UniversalClient
    	if *cluster {
    		// 连接 Redis 集群
    		portList := strings.Split(*port, ",")
    		addrs := make([]string, len(portList))
    		for i, p := range portList {
    			addrs[i] = fmt.Sprintf("%s:%s", *host, p)
    		}
    		fmt.Println("Redis 集群地址:", addrs)
    		rdb = redis.NewClusterClient(&redis.ClusterOptions{
    			Addrs: addrs,
    			Password: *password,
    		})
    	} else {
    		// 连接 Redis 单机
    		rdb = redis.NewClient(&redis.Options{
    			Addr:     fmt.Sprintf("%s:%s", *host, *port),
    			Password: *password,
    			DB:       *db,
    		})
    	}
    
    	if err := rdb.Ping(ctx).Err(); err != nil {
    		fmt.Println("连接 Redis 失败:", err)
    		return
    	}
    
    	// 创建并发客户端
    	var wg sync.WaitGroup
    	for i := 0; i < *clients; i++ {
    		wg.Add(1)
    		go func() {
    			defer wg.Done()
    			for j := 0; j < *requests; j++ {
    				key := fmt.Sprintf("key-%d-%d", i, j)
    				value := make([]byte, *dataSize)
    				logger.Println("当前执行操作:", *cmdType, "Key:", key, "执行请求数量:", *requests)
    				if *cmdType == "set" {
    					err := rdb.Set(ctx, key, value, 0).Err()
    					if err != nil {
    						panic(err)
    					}
    				} else if *cmdType == "get" {
    					_, err := rdb.Get(ctx, key).Result()
    					if err != nil && err != redis.Nil {
    						panic(err)
    					}
    				} else {
    					panic(fmt.Sprintf("不支持的命令类型:%s", *cmdType))
    				}
    			}
    		}()
    	}
    
    	// 等待所有客户端执行完成
    	start := time.Now()
    	wg.Wait()
    	end := time.Now()
    
    	// 输出测试结果
    	duration := end.Sub(start)
    	qps := float64(*requests) / duration.Seconds()
    	fmt.Printf("执行请求数量:%d\n", *requests)
    	fmt.Printf("并发客户端数量:%d\n", *clients)
    	if *cmdType == "set" {
    		fmt.Printf("写入数据大小:%d\n", *dataSize)
    	}
    	fmt.Printf("Redis 命令类型:%s\n", *cmdType)
    	fmt.Printf("总共用时:%v\n", duration)
    	fmt.Printf("平均每秒请求数量:%f\n", qps)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    5. 测试结果

    我们可以使用以下命令行参数来测试Redis单机和Redis集群的性能:

    测试Redis单机

    go run main.go -h localhost -p 6379 -n 10000 -c 50 -d 1024 -t set
    
    
    • 1
    • 2

    执行结果如下:

    执行请求数量:10000
    并发客户端数量:50
    写入数据大小:1024
    Redis命令类型:set
    总共用时:10.5033712s
    平均每秒请求数量:952.957627
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试Redis集群

    go run main.go -h 10.1.4.7 -p 6379,6380,6381 -n 10000 -c 50 -d 1024 -t set --cluster
    
    • 1

    执行结果如下:

    Redis集群地址: [10.39.45.47:6379 10.39.45.47:6380 10.39.45.47:6381]
    执行请求数量:10000
    并发客户端数量:50
    写入数据大小:1024
    Redis命令类型:set
    总共用时:9.6948692s
    平均每秒请求数量:1031.903858
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用截图

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    6. 编译

    也可以编译后使用

    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o redis_performance main.go
    
    • 1

    编译后的文件名:redis_performance
    将这个文件上传服务器后 chmod赋予权限,然后./redis_performance运行即可

    7. 总结

    本文介绍了如何使用Go语言测试Redis的性能,通过测试脚本可以方便地测试Redis在不同场景下的性能表现。在实际应用中,我们可以根据测试结果来调整Redis的配置,以便更好地满足应用需求。

  • 相关阅读:
    java计算机毕业设计列车票务信息管理系统源码+数据库+lw文档+系统
    猿创征文 |《深入浅出Vue.js》打卡Day7
    e6.利用 docker 快速部署自动化运维平台
    【网络安全---ICMP报文分析】Wireshark教程----Wireshark 分析ICMP报文数据试验
    RunApi在发送请求的时候添加Token
    python-爬虫-爬取中华人民共和国农业农村部网站公开的农产品批发价格中的蔬菜价格周数据
    RT-Thread 下的文件内容对比 MSH shell cmd 命令实现方法
    关系数据库系统中的 NULL 值及其用途
    【教3妹学编程-算法题】最大化数组末位元素的最少操作次数
    计算机网络第六章——应用层(下)
  • 原文地址:https://blog.csdn.net/weixin_41853064/article/details/134011152