图床项目性能测试

简介: 图床项目性能测试

一、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


目录
相关文章
|
25天前
|
人工智能 测试技术 项目管理
测试不再碎片化:AI智能体平台「项目资料套件」功能上线!
在实际项目中,需求文档分散、整理费时、测试遗漏等问题常困扰测试工作。霍格沃兹推出AI智能体测试平台全新功能——项目资料套件,可将多个关联文档打包管理,并一键生成测试用例,提升测试完整性与效率。支持套件创建、文档关联、编辑删除及用例生成,适用于复杂项目、版本迭代等场景,助力实现智能化测试协作,让测试更高效、更专业。
|
9天前
|
测试技术 UED 开发者
性能测试报告-用于项目的性能验证、性能调优、发现性能缺陷等应用场景
性能测试报告用于评估系统性能、稳定性和安全性,涵盖测试环境、方法、指标分析及缺陷优化建议,是保障软件质量与用户体验的关键文档。
|
2月前
|
Java 测试技术 Spring
简单学Spring Boot | 博客项目的测试
本内容介绍了基于Spring Boot的博客项目测试实践,重点在于通过测试驱动开发(TDD)优化服务层代码,提升代码质量和功能可靠性。案例详细展示了如何为PostService类编写测试用例、运行测试并根据反馈优化功能代码,包括两次优化过程。通过TDD流程,确保每项功能经过严格验证,增强代码可维护性与系统稳定性。
149 0
|
2月前
|
人工智能 数据可视化 测试技术
UAT测试排程工具深度解析:让验收测试不再失控,项目稳稳上线
在系统交付节奏加快的背景下,“测试节奏混乱”已成为项目延期的主因之一。UAT测试排程工具应运而生,帮助团队结构化拆解任务、清晰分配责任、实时掌控进度,打通需求、测试、开发三方协作闭环,提升测试效率与质量。本文还盘点了2025年热门UAT工具,助力团队选型落地,告别靠表格和群聊推进测试的低效方式,实现有节奏、有章法的测试管理。
|
7月前
|
人工智能 自然语言处理 测试技术
Potpie.ai:比Copilot更狠!这个AI直接接管项目代码,自动Debug+测试+开发全搞定
Potpie.ai 是一个基于 AI 技术的开源平台,能够为代码库创建定制化的工程代理,自动化代码分析、测试和开发任务。
580 19
Potpie.ai:比Copilot更狠!这个AI直接接管项目代码,自动Debug+测试+开发全搞定
|
7月前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
823 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
7月前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
319 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
8月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
203 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
10月前
|
监控 安全 测试技术
如何在实际项目中应用Python Web开发的安全测试知识?
如何在实际项目中应用Python Web开发的安全测试知识?
178 61
|
10月前
|
机器学习/深度学习 算法 UED
在数据驱动时代,A/B 测试成为评估机器学习项目不同方案效果的重要方法
在数据驱动时代,A/B 测试成为评估机器学习项目不同方案效果的重要方法。本文介绍 A/B 测试的基本概念、步骤及其在模型评估、算法改进、特征选择和用户体验优化中的应用,同时提供 Python 实现示例,强调其在确保项目性能和用户体验方面的关键作用。
334 6