一个集成redis-benchmark的redis压测的脚本
支持 单节点 主从 sentinel cluster (sentinel的还没写)
出于高可用的考虑,你还可以用高可用的ip做压力测试
需要调用redis-benchmark 用来测试不同版本redis7 同样写入速率和相同数据量下 redis占用内存大小
写了很多def,改天统一合并到一个类里面去
使用方式

python3 newtest.py -h xxxxxx -P 6379 -t 2 -a xxxxxx <可选> -H xxxx
#!/usr/bin/python3
import argparse
import subprocess
import sys
from datetime import datetime

import redis

standalone = 0
sentinel = 1
cluster = 2

v = 6
ips = ''
shard1_ip = ''
shard2_ip = ''
shard3_ip = ''
if v == 6:
    flush = "92619_dont_run_flushall_rudely"
elif v == 7:
    flush = "92618_dont_run_flushall_rudely"


# cmd = "/home/redis/redistest/src/redis-benchmark -h {}  --cluster -p 6379 -q -a {} -p 6379 -t set   " \
#       "--threads 8 -P 100 -q -r 10000 -d 1024".format(
#     ips, passwd)


def getredis_used_Mem(ip, passwd, port):
    r = redis.StrictRedis(host=ip, password=passwd, port=port)
    mem = ()['used_memory']
    r.close()
    return mem


def init_mem(ip, passwd, port):
    r = redis.StrictRedis(host=ip, password=passwd, port=port)
    r.execute_command(flush)
    r.close()


def humansize(iput):
    b = 1
    B = b * 1024
    MB = B * 1024
    GB = MB * 1024
    TB = GB * 1024
    if iput > TB:
        return str(iput / TB) + " TB"
    elif iput > GB:
        return str(iput / GB) + " GB"
    elif iput > MB:
        return str(iput / MB) + " MB"
    elif iput > B:
        return str(iput) + " Bit"
    else:
        return str(iput) + " bit"


def timehuman(iput):
    s = 1
    m = s * 60
    h = m * 60
    d = h * 24
    if iput > d:
        return str(iput / d) + " days"
    elif iput > h:
        return str(iput / h) + " hours"
    elif iput > m:
        return str(iput / m) + " mins"
    else:
        return str(iput) + " seconds"


def get_master_ip(ip, passwd, port):
    r = redis.StrictRedis(host=ip, password=passwd, port=port)
    if ()['role'] == "slave":
        masterip = ()['master_host']
        r.close()
        return masterip
    else:
        return ip


def parse_args(args):
    """parser agrs for this file"""
    parser = argparse.ArgumentParser(description='Parse Args you want', add_help=False)
    connect_setting = parser.add_argument_group('connect setting')
    connect_setting.add_argument('-h', '--host', dest='host', type=str,
                                 help='Host the Redis database server located\n  redis单节点/主从/cluster的任意一个节点的ip地址',
                                 default='127.0.0.1')
    connect_setting.add_argument('-H', '--lbc_ip', dest='ips', type=str,
                                 help='Host the Redis database lbc server located\n  redis上层网络地址,可以是dns lbc或者proxy地址',
                                 default='127.0.0.1')
    connect_setting.add_argument('-a', '--passwd', dest='passwd', type=str,
                                 help='password for redis', default=None)
    connect_setting.add_argument('-P', '--port', dest='port', type=str,
                                 help='port for redis', default=None)
    parser.add_argument('-t', '--archtype',
                        help='the architecture type of the redis database [standalone sentinel cluster]',
                        default=0)
    return parser


def command_line_args(args):
    parser = parse_args(args)
    args = parser.parse_args(args)
    return args


def get_cluster_all_master_nodes(realip, passwd, port):
    cluster_master_ip_list = []
    r = redis.r = redis.StrictRedis(host=realip, password=passwd, port=port, db=0)
    clusterinfo = r.cluster("nodes")
    for nodes in clusterinfo:
        if 'master' in clusterinfo[nodes]["flags"]:
            cluster_master_ip_list.append(nodes.split(':')[0])
    print(cluster_master_ip_list)
    return cluster_master_ip_list


def runbenchmark(type, proxyip, realip, passwd, port):
    if type == cluster:
        cmd = "/home/redis/redistest/src/redis-benchmark -h {}  --cluster -p 6379 -q -a {} -p {} -t set  -n 100000000 " \
              "--threads 8 -P 100 -q -r 10000000 ".format(
            proxyip, passwd, port)
        cluster_masters = get_cluster_all_master_nodes(realip, passwd, port)
        starttime = datetime.now()
        cluster_mem_start = 0
        cluster_mem_end = 0
        for ip in cluster_masters:
            init_mem(ip, passwd, port)
            cluster_mem_start = cluster_mem_start + getredis_used_Mem(ip, passwd, port)

        if subprocess.run(cmd, shell=True, check=True).returncode == 0:
            endtime = datetime.now()
            duringtime = endtime - starttime
            for ip in cluster_masters:
                cluster_mem_end = cluster_mem_start + getredis_used_Mem(ip,passwd,port)
            output = abs(cluster_mem_end - cluster_mem_start)

        else:
            err_msg = 'run {} failed'.format(cmd)
            raise Error(err_msg)


    else:
        cmd = "/home/redis/redistest/src/redis-benchmark -h {}  -p 6379 -q -a {} -p {} -t set  -n 1000000 " \
              "--threads 8 -P 100 -q -r 1000000 ".format(
            proxyip, passwd, port)

        init_mem(proxyip, passwd, port)
        mem_start = getredis_used_Mem(realip, passwd, port)
        starttime = datetime.now()

        if subprocess.run(cmd, shell=True, check=True).returncode == 0:
            mem_end = getredis_used_Mem(realip,passwd,port)
            endtime = datetime.now()
            duringtime = endtime - starttime
            output = abs(mem_end - mem_start)
        else:
            err_msg = 'run {} failed'.format(cmd)
            raise Error(err_msg)

    print("写完数据总共耗时{},内存占用为{}".format(timehuman(duringtime.seconds), humansize(output)))


class Error(ValueError):
    pass


def main():
    args = command_line_args(sys.argv[1:])
    # lbc dns proxy 统一叫proxy
    proxy_ip = args.ips
    passwd = args.passwd
    port = args.port
    masterIp = get_master_ip(args.host, passwd, port)
    if not proxy_ip:
        ip = proxy_ip
    else:
        ip = masterIp
    if int(args.archtype) == standalone:
        runbenchmark(standalone, ip, masterIp, passwd, port)
    elif int(args.archtype) == sentinel:
        runbenchmark(sentinel, ip)
    elif int(args.archtype) == cluster:
        runbenchmark(cluster, ip, masterIp, passwd, port)
    else:
        raise f'不支持的redis架构类型{Error(args.archtype)}'


if __name__ == '__main__':
    main()