Monday, October 11, 2010

足够数目的getdents调用与文件数目引发的问题

网站的速度很慢。要求给个理由。于是登机top了一把。如下

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                              
29131 liangqin  16   0 15068 3444  816 R 11.7  0.0   0:00.72 top                                                                                   
16371 kmmaster  16   0  181m 8484 3128 D  5.2  0.1   0:01.20 httpd                                                                                 
 5726 kmmaster  15   0  182m 9352 3564 S  3.9  0.1   0:02.24 httpd                                                                                 
32548 kmmaster  16   0  183m 9.8m 3348 D  3.9  0.1   0:06.16 httpd                                                                                
 6199 kmmaster  16   0  183m 9444 3452 D  2.6  0.1   0:01.89 httpd                                                                                 
 7697 kmmaster  16   0  182m 8848 3184 D  2.6  0.1   0:01.94 httpd                                                                                 
10536 kmmaster  16   0  181m 8692 3332 D  2.6  0.1   0:01.93 httpd                                                                                 
15102 kmmaster  16   0  181m 8420 3060 D  2.6  0.1   0:01.37 httpd                                                                                 
17993 kmmaster  16   0  181m 8708 3292 D  2.6  0.1   0:04.16 httpd                                                                                 
23185 kmmaster  16   0  182m 9420 3428 D  2.6  0.1   0:00.61 httpd                                                                                
30189 kmmaster  16   0  181m 8724 3308 D  2.6  0.1   0:05.91 httpd                                                                                 
30337 kmmaster  16   0  183m 9.9m 3448 D  2.6  0.1   0:02.71 httpd      


使用strace命令查看D状态的httpd, 都是调用getdents, stat, unlink等IO函数, 如:
stat("/tmp/sess_bc45d5d1dd8739acceff8a3e0fec0585", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0

使用ls, find之类的工具都无法对此目录(指/tmp)进行数据查看。行为freeze。也是进入D状态。

本想使用python的os.listdir函数的。但这个函数是读完目录的entry后才返回list的。 也是要慢很长时间。

于是使用下面的C代码:
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>

int main(int argc, char * argv[])
{
        DIR *dirp = opendir("/tmp");
        struct dirent *retval;
        long long int t;
        for(; ; ){
                retval = readdir(dirp);
                if (retval == NULL) {break;}
                else {printf("%s\n", retval->d_name); t++;}
        }
        printf("%lld\n", t);
}  
可以知道目录文件总数是 221346

httpd的进程数有3K!每个需要session的进程都要读/tmp目录下的entry, 这个行为会对3K数目的httpd进程有很大的影响吗?

于是自己写了个测试代码, 目的就是测试众多的readdir函数是否对进程有影响:
#coding:utf-8
import time
import os

for i in range(300):
    pid = os.fork()
    if pid > 0:
        break

for r in range(30):
    time.sleep(0.1)
    os.listdir("/tmp")

代码很简单, 但是对于200K条目的directory来说, 很给力!!出现大量的D状态进程:
(........被截去......)
905       7072  0.1  0.0  84244 11628 pts/2    D+   14:45   0:00 python listdir.py
905       7073  0.1  0.1  85136 12448 pts/2    D+   14:45   0:00 python listdir.py
905       7074  0.1  0.1  85136 12628 pts/2    D+   14:45   0:00 python listdir.py
905       7075  0.1  0.1  86304 13588 pts/2    D+   14:45   0:00 python listdir.py
905       7076  0.1  0.0  84764 12264 pts/2    D+   14:45   0:00 python listdir.py
905       7077  0.1  0.0  84504 12036 pts/2    D+   14:45   0:00 python listdir.py
905       7078  0.1  0.1  85136 12672 pts/2    D+   14:45   0:00 python listdir.py
905       7079  0.1  0.1  85916 13360 pts/2    D+   14:45   0:00 python listdir.py
905       7080  0.1  0.1  85916 13448 pts/2    D+   14:45   0:00 python listdir.py
905       7081  0.2  0.1  89728 16964 pts/2    D+   14:45   0:00 python listdir.py
905       7082  0.2  0.1  88268 15776 pts/2    D+   14:45   0:00 python listdir.py
905       7083  0.2  0.1  88268 15596 pts/2    D+   14:45   0:00 python listdir.py
905       7084  0.2  0.1  87344 14820 pts/2    D+   14:45   0:00 python listdir.py
905       7085  0.1  0.1  85136 12628 pts/2    D+   14:45   0:00 python listdir.py
905       7086  0.2  0.1  86304 13812 pts/2    D+   14:45   0:00 python listdir.py
(......被截去.......)

机器的内存使用量快速上升。

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.