图床项目性能测试

简介: 图床项目性能测试

一、FastDFS文件性能测试



小规模测试的时候,建议一台客户端机器只模拟一个客户端 ./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查看到的一些基本参数信息

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 = "472251823@qq.com",
        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


相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
4月前
|
监控 安全 测试技术
从开发到测试再到发布,全方位解析项目上线的完美路程!
从开发到测试再到发布,全方位解析项目上线的完美路程!
126 0
|
6月前
|
网络协议 安全 Linux
12. 测试搭建百万并发项目
12. 测试搭建百万并发项目
72 0
|
6月前
|
JavaScript 测试技术 API
vue項目加入单元测试模块,使用jest
vue項目加入单元测试模块,使用jest
60 0
|
7月前
|
监控 安全 测试技术
从开发到测试再到发布,全方位解析项目上线的完美路程!
从开发到测试再到发布,全方位解析项目上线的完美路程!
|
5月前
|
移动开发 前端开发 JavaScript
VSCode设置类似Webstorm那样可以用本地局域网IP地址访问自己开发的测试项目,vs code 前端如何以服务器模式打开?
VSCode设置类似Webstorm那样可以用本地局域网IP地址访问自己开发的测试项目,vs code 前端如何以服务器模式打开?
VSCode设置类似Webstorm那样可以用本地局域网IP地址访问自己开发的测试项目,vs code 前端如何以服务器模式打开?
|
4月前
|
存储 Rust 测试技术
【一起学Rust · 项目实战】命令行IO项目minigrep——测试驱动开发完善功能
【一起学Rust · 项目实战】命令行IO项目minigrep——测试驱动开发完善功能
95 0
|
6月前
|
JavaScript Java 关系型数据库
ssm+vue的在线测试管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。
ssm+vue的在线测试管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。
|
2月前
|
Java PHP 数据库
在护卫神上部署javaWeb项目,已经测试通过
在护卫神上部署javaWeb项目,已经测试通过
12 0
|
4月前
|
SQL 安全 测试技术
项目迁移到云服务器,如何做迁移测试?
项目迁移到云服务器,如何做迁移测试?
|
5月前
|
监控 Java
Pinpoint【部署 02】Pinpoint Agent 安装启动及监控 SpringBoot 项目案例分享(添加快速测试math-game.jar包)
Pinpoint【部署 02】Pinpoint Agent 安装启动及监控 SpringBoot 项目案例分享(添加快速测试math-game.jar包)
81 0

热门文章

最新文章