如今,这一问题到自己身上时却不以为然。
今天在测试一下项目性能时,需要向服务器Post文件。服务器会解析文件内容,然后走业务逻辑。
测试有以下两种场景:
1、 上报“单文件”:Post携带的内容中仅包含一个文件的内容;
2、 上报“多文件”:Post携带的内容中包含多个文件的内容。
两种场景使用的文件是现成,放在不同的目录。每种场景的文件放在各自目录里,没有子目录。
简单介绍一点逻辑:“单文件”有114133个,“多文件”有16306个。一个“多文件”里约包含7个单文件。
事务标识方式:按次计数,处理一个单文件计一个事务,处理完一个多文件只计一个事务。
所以,理论上报单文件一定比上报多文件快!因为上报的文件大小小、网络流量少、服务器处理的事情也少。
性能测试过程发现一个诡异的现象:
服务器处理单文件的速度要比处理多文件慢。
首先,还是怀疑应用程序的问题。幸运的是应用程序是C语言写的,可使用ltrace 、strace进行跟踪。
不幸的是,对比跟踪结果没有发现问题,而且看起来逻辑很正确。
然后,开始改程序。把逻辑代码都注释掉,问题仍然重现。这下不得不怀疑我的测试方法了!
到这步问题基本就明朗了,矛头指向文件系统。
下图标记了文件数量与响应时间(脚本时间、网络时间):
图的上半段是小文件的测试结果,下半段是大文件的测试结果。
图中已证明了两个结论:
1、 Post单文件的时间主要耗在脚本上(实际上就耗在读取文件上);
2、 Post多文件的网络处理时间要比Post单文件要长(说明服务器处理多个文件确实比处理单文件慢)。
OK,接下来就要拆分目录了。处理文本,Linux最善长了:
#!/bin/bash -x# 将目录中的所有文件转移到子目录中
baseDir=/data/appdatas/postfiles
mvScript=$baseDir/mvFiles.sh
# 生成新的文件列表
function mkFileList(){
awk 'BEGIN{
i=11413; /* oldFileList 的总行数 */
j=0
}{
for(j=0;j<10;j++){
if(NR>j*i && NR <=(j+1)*i){
printf("%d\\\\%s\n",j+1,$1)
}
}
}' $baseDir/oldFileList > $baseDir/newFileList
}
# 移动文件到新目录
function mvFiles(){
echo '#!/bin/bash -x' > $mvScript
awk 'BEGIN{
i=11413; /* oldFileList 的总行数 */
j=0
}{
for(j=0;j<10;j++){
if(NR>j*i && NR <=(j+1)*i){
printf("mv ./%s ./%d/%s\n",$1,j+1,$1)
}
}
}' $baseDir/oldFileList >> $mvScript
chmod +x $mvScript
$mvScript
}
# 创建新目录
function mkDirs(){
for i in `seq 10`
do
mkdir -p ./$i
done
}
# 脚本开始执行
cd $baseDir
mkFileList
mkDirs
mvFiles
感慨一下,awk真是强大!