图床项目性能测试

文章目录

  • 一、FastDFS文件性能测试
    • 1.1 上传文件测试
    • 1.2 下载测试
    • 1.3 删除文件测试
    • 1.4 如何提高
  • 二、图床项目wrk+lua性能测试
    • 2.1 wrk
    • 2.2 MySQL索引优化
    • 2.2 注册测试
      • 2.2.1 无索引性能
      • 2.2.2 有索引性能
    • 2.3 登录测试
      • 2.3.1 无索引性能
      • 2.3.2 有索引性能
    • 2.4 读取文件测试
      • 2.4.1 无索引性能
      • 2.4.2 有索引性能

一、FastDFS文件性能测试

图床项目性能测试_第1张图片
小规模测试的时候,建议一台客户端机器只模拟一个客户端 ./test_upload.sh 1 。

具体来说,进入fastdfs安装目录,进入test目录下,进行make

cd /home/zxm/tuchuang/fastdfs/test
make

./gen_files 生成测试文件;

./test_delete 测试删除文件

./test_download 测试下载文件;

./test_upload 测试上传文件;

1.1 上传文件测试

 # 生成5k、50k、200k、1M、10M、100M的文件各一个
 ./gen_files 
 
 # 可以模拟十个并发客户端。.0、.1、....、.9是客户端序号
 #./test_upload.sh   

# 只测一个客户端,0代表编号
 ./test_upload 0

# 结果查看
cd upload

在 stat_by_file_type.0 查看上传的情况

#file_type total_count success_count time_used(ms)
5K 5000 5000 707
50K 1000 1000 248
200K 500 500 599
1M 50 50 382
10M 5 5 269
100M 1 1 606
文件规格 上传次数 成功次数 总耗时 ms 平均耗时 ms TPS
5k 5000 5000 707 0.141 7072
50k 1000 1000 248 0.248 4032
200k 500 500 599 1.198 835
1M 50 50 382 7.640 131
10M 5 5 269 53.800 19
100M 1 1 606 606 2

TPS: Transactions Per Second 也就是事务数/秒。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数

1.2 下载测试

./test_download 0
#file_type total_count success_count time_used(ms)
5K 1162088 1162088 574
50K 220357 220357 117		
200K 119790 119790 116		# tps = 1032672
1M 12396 12396 8630

1.3 删除文件测试

./test_delete 0
#file_type total_count success_count time_used(ms)5K 5000 5000 73
50K 1000 1000 9
200K 500 500 6		# tps = 8333
1M 50 50 1
10M 5 5 5
100M 1 1 15

1.4 如何提高

提升上传性能的方法:
1)增加group (水平扩展)
2)增加带宽(带宽能力)
3)使用读写性能高的磁盘
单纯增加每个group的storage只能应对上传峰值,不能从根本上提升上传能力。而且storage增加,还会增加上传文件同步到同组storage的流程。

提升下载性能的方法:
1)增加storage (少写多读的场景)
2)增加group
3)增加带宽
4)使用读性能高的磁盘

二、图床项目wrk+lua性能测试

2.1 wrk

以下是使用wrk查看到的一些基本参数信息
图床项目性能测试_第2张图片
N代表数字参数,支持国际单位 (1k, 1M, 1G)
T代表时间参数,支持时间单位 (2s, 2m, 2h)

例如:wrk -c 20 -t 2 -d 20s --latency http://192.168.1.34
建立20个TCP连接,使用两个线程,用时20秒,对http://192.168.1.34进行压测。
返回结果

Running 20s test @ http://192.168.0.143
 2 threads and 20 connections
Thread Stats  Avg   Stdev   Max  +/- Stdev
      (平均值)(标准差)(最大值)(正负一个标准差所占比例)
 Latency   9.35ms   1.91ms  81.96ms  96.92%
 (延迟)
 Req/Sec   1.08k   73.16   1.52k   88.50%
 (处理中的请求数)
Latency Distribution(延迟分布)
  50%   9.03ms
  75%   9.45ms
  90%   9.97ms
  99%  17.26ms(99分位的延迟)
 43019 requests in 20.03s, 170.79MB read(20.03s秒内共处理完成了43019个请求,读取了
170.79MB数据)
Requests/sec:  2148.24  (平均每秒处理完成2148.24个请求)
Transfer/sec:    8.53MB (平均每秒读取数据8.53MB)

2.2 MySQL索引优化

正式进行测试之前,先介绍一下图床项目的MySQL优化地方。

1、user_info表
被调用涉及到where:

select password from user_info where user_name='%s'
select * from user_info where user_name='%s'

主要匹配user_name
索引:UNIQUE KEY uq_user_name ( user_name ) 创建唯一索引:1查找更快速;2.不允许重复;

2、user_file_list 表
被调用涉及到where:

select count(*) from user_file_list where user='%s'
select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where
user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d"
update user_file_list set shared_status = 1 where user = '%s' and md5 = '%s' and file_name = '%s'
update user_file_list set shared_status = 0 where user = '%s' and md5 = '%s' and file_name = '%s'
select * from user_file_list where user = '%s' and md5 = '%s' and file_name = '%s'

联合索引:KEY idx_user_md5_file_name ( user , md5 , file_name )

3、share_picture_list 表-考虑

select * from share_picture_list where user='%s' 
select share_picture_list.user, share_picture_list.filemd5,
share_picture_list.file_name,share_picture_list.urlmd5, share_picture_list.pv,
share_picture_list.create_time, file_info.size from file_info, share_picture_list where
share_picture_list.user = '%s' and file_info.md5 = share_picture_list.filemd5 limit %d, %d"
select * from share_picture_list where user = '%s' and urlmd5 = '%s'
select filemd5 from share_picture_list where urlmd5 = '%s' 

索引:KEY idx_user_filemd5 ( user , filemd5 ),
KEY idx_urlmd5_user ( urlmd5 , user )

两两匹配可以调换顺序,比如(user,urlmd5)可以和(urlmd5,user)匹配,但是一个不行。因此若还有单个urlmd5,根据最左匹配原子,必须把urlmd5放在user前面才可以匹配。

4、share_file_list表

select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list
where file_info.md5 = share_file_list.md5 limit %d, %d
delete from share_file_list where user = '%s' and md5 = '%s
update share_file_list set pv = %d where md5 = '%s' and file_name = '%s'
delete from share_file_list where user = '%s' and md5 = '%s' and file_name = '%s',
select * from share_file_list where md5 = '%s' and file_name = '%s'

索引:KEY idx_filename_md5_user ( file_name , md5 , user ),
KEY idx_md5_user ( md5 , user )

5、file_info

select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where
file_info.md5 = share_file_list.md5 limit %d, %d
file_info where md5 = '%s'

索引:KEY uq_md5 ( md5 (8)) – 前缀索引
md5有32个字符,一一匹配很费时。一般前8个匹配就能判断。

2.2 注册测试

指令

#  http://127.0.0.1/api/reg如果是跨机器测试则填写目标ip的地址。
wrk -c 20 -t 20 -d 5s --latency -s scripts/reg.lua http://127.0.0.1/api/reg

reg.lua大致的原理:
1)通过随机字符串给nickName和userName赋值。
2)然后发起post请求

-- reg.lua
-- 引入dkjson,之所以不使用cjson是因为有版本兼容的问题
local dkjson = require("dkjson")  

-- 产生随机数
function random(n, m)
    math.randomseed(os.clock()*math.random(1000000,90000000)+math.random(1000000,90000000))
    return math.random(n, m)
end
-- 产生随机字符串
function randomLetter(len)
    local rt = ""
    for i = 1, len, 1 do
            rt = rt..string.char(random(97,122))
    end
    return rt
end

request = function()
    local request_body = {
        email = "[email protected]",
        firstPwd = "e10adc3949ba59abbe56e057f20f883e",
        nickName = randomLetter(15),
        phone = "18612345678",
        userName = randomLetter(15)
    }
    local body = dkjson.encode(request_body, {indent = true});
    -- print("req ", body)
    wrk.method = "POST"
    wrk.body   =  body
    wrk.headers["Content-Type"] = "application/json"
    return  wrk.format(wrk.method,"/api/reg", wrk.headers, wrk.body)
end
response = function(status, headers, body)
    -- print(body) --调试用,正式测试时需要关闭,因为解析response非常消耗资源
end

2.2.1 无索引性能

Running 5s test @ http://127.0.0.1/api/reg				
  20 threads and 20 connections				
  Thread Stats   Avg      Stdev     Max   +/- Stdev				
    Latency    49.78ms    6.19ms  75.22ms   88.58%				
    Req/Sec    19.95      3.52    60.00     91.97%				
  Latency Distribution				
     50%   49.76ms				
     75%   52.65ms				
     90%   55.28ms				
     99%   61.33ms				
  2041 requests in 5.10s, 561.99KB read				
Requests/sec:    400.37				
Transfer/sec:    110.24KB

2.2.2 有索引性能

Running 5s test @ http://127.0.0.1/api/reg		
  20 threads and 20 connections		
  Thread Stats   Avg      Stdev     Max   +/- Stdev		
    Latency    26.22ms   66.13ms 435.75ms   93.89%		
    Req/Sec   100.58     24.94   180.00     75.76%		
  Latency Distribution		
     50%    9.49ms		
     75%   12.07ms		
     90%   21.05ms		
     99%  381.12ms		
  9628 requests in 5.09s, 2.59MB read		
Requests/sec:   1893.16		
Transfer/sec:    521.58KB	

2.3 登录测试

wrk -c 20 -t 20 -d 5s --latency -s scripts/login.lua http://127.0.0.1/api/login

需要根据自己的用户名和密码修改

-- login.lua 
request = function()
    -- print("req")
    wrk.method = "POST"
    -- 用户名 handsome1;密码:这里是123456做md5的结果
    wrk.body = '{"user":"handsome1","pwd":"e10adc3949ba59abbe56e057f20f883e"}'
    wrk.headers["Content-Type"] = "application/json"
    return  wrk.format(wrk.method,"/api/login",wrk.headers, wrk.body)
end
response = function(status, headers, body)
    -- print(body) --调试用,正式测试时需要关闭,因为解析response非常消耗资源
end

2.3.1 无索引性能

Running 5s test @ http://127.0.0.1/api/login
  20 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    22.51ms   10.18ms  95.65ms   73.28%
    Req/Sec    45.02     10.68    80.00     67.39%
  Latency Distribution
     50%   21.07ms
     75%   27.78ms
     90%   34.92ms
     99%   55.82ms
  4566 requests in 5.08s, 1.42MB read
Requests/sec:    897.96
Transfer/sec:    285.01KB

2.3.2 有索引性能

Running 5s test @ http://127.0.0.1/api/login	
  20 threads and 20 connections	
  Thread Stats   Avg      Stdev     Max   +/- Stdev	
    Latency    12.70ms    4.81ms  58.82ms   80.24%	
    Req/Sec    79.78     13.38   140.00     79.50%	
  Latency Distribution	
     50%   12.02ms	
     75%   14.64ms	
     90%   17.65ms	
     99%   30.60ms	
  8070 requests in 5.10s, 2.50MB read	
Requests/sec:   1582.73	
Transfer/sec:    502.26KB	

2.4 读取文件测试

wrk -c 20 -t 20 -d 2s --latency -s scripts/myfiles.lua http://127.0.0.1/api/myfiles&cmd=normal

目前设置最多拉取10个文件信息,这里需要token,浏览器登录的时候通过F12观察调试窗口获取。

-- myfiles.lua
request = function()
    -- print("req")
    wrk.method = "POST"
    -- user: handsome1;token:浏览器登录时通过F12从浏览器调试窗口获取
    wrk.body = '{"user":"handsome1","count": 10,"start": 0,"token":"opttrtsbzvwxxftwqeuzrqzsnjmmdnns"}'
    wrk.headers["Content-Type"] = "application/json"
    return  wrk.format(wrk.method,"/api/myfiles&cmd=normal",wrk.headers, wrk.body)
end
response = function(status, headers, body)
    -- print(body) --调试用,正式测试时需要关闭,因为解析response非常消耗资源
end

2.4.1 无索引性能

Running 2s test @ http://127.0.0.1/api/myfiles
  20 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    13.17ms    6.56ms  61.17ms   88.82%
    Req/Sec    78.71     14.88   120.00     75.12%
  Latency Distribution
     50%   11.90ms
     75%   14.71ms
     90%   18.26ms
     99%   45.08ms
  3300 requests in 2.10s, 0.95MB read
Requests/sec:   1573.67
Transfer/sec:    464.30KB

2.4.2 有索引性能

Running 2s test @ http://127.0.0.1/api/myfiles
  20 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.95ms    2.94ms  27.88ms   74.27%
    Req/Sec   126.69     19.30   191.00     69.86%
  Latency Distribution
     50%    7.58ms
     75%    9.46ms
     90%   11.46ms
     99%   18.19ms
  5288 requests in 2.10s, 1.42MB read
Requests/sec:   2518.11
Transfer/sec:    693.73KB

本专栏知识点是通过<零声教育>的系统学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接,详细查看详细的服务器课程

你可能感兴趣的:(#,图床项目,fastdfs,wrk,c/c++,后端)