文章目录
- 一、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文件性能测试
小规模测试的时候,建议一台客户端机器只模拟一个客户端 ./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
本专栏知识点是通过<零声教育>的系统学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接,详细查看详细的服务器课程