我有一个经常使用的 Linux 应用程序,它喜欢在工作时创建大量临时文件。基本上,它的软件可以自动对电路板进行布线,并且在布线过程中,它会创建和删除大量临时文件。
扫描 open 命令时我的 strace 输出如下所示:
12:09:52.677525 open("/tmp/e000134A.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:52.677777 open("/tmp/e000134A.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:52.871198 open("/tmp/e000134B.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:52.871342 open("/tmp/e000134B.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:53.092441 open("/tmp/e000134C.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:53.092563 open("/tmp/e000134C.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:53.292663 open("/tmp/e000134D.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:53.292779 open("/tmp/e000134D.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:53.452220 open("/tmp/e000134E.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:53.452310 open("/tmp/e000134E.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:53.630176 open("/tmp/e000134F.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:53.630275 open("/tmp/e000134F.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:53.797461 open("/tmp/e0001350.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:53.797566 open("/tmp/e0001350.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:53.968627 open("/tmp/e0001351.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:53.968727 open("/tmp/e0001351.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:09:54.145310 open("/tmp/e0001352.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:09:54.145417 open("/tmp/e0001352.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
并且呼叫不断重复,直到我停止操作。
我注意到在我的临时文件夹中创建的一个文件大约有 90K,但大多数时候它们是 0 字节。
我尝试通过以下方式提高操作速度:
我调整了启动参数以允许更大的内存驱动器,然后在启动需要 /tmp 文件夹的任何内容之前添加了这两行:
mke2fs -cc -b 1024 -m 0 /dev/ram0 50000
mount -o async,nodev,noatime,nodiratime,noiversion,nomand,norelatime /dev/ram0 /tmp
我还使用 ionice 执行了该应用程序:
ionice -c1 -n0 appname
以下是我的 strace 的更多内容,涉及它如何处理临时文件从创建到删除的过程:
12:17:02.905620 stat64("/tmp/", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=1024, ...}) = 0
12:17:02.905719 access("/tmp/", R_OK|W_OK|X_OK) = 0
12:17:02.905782 open("/tmp/e0001C6D.tmp", O_RDWR|O_CREAT|O_APPEND, 0666) = 8
12:17:02.905851 close(8) = 0
12:17:02.905886 open("/tmp/e0001C6D.tmp", O_RDWR|O_CREAT|O_TRUNC, 0666) = 8
12:17:02.905933 fstat64(8, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
12:17:02.905994 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7c5c000
12:17:02.906044 write(8, "\1\0\224\10\30\206\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
12:17:02.906117 write(8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 63488) = 63488
12:17:02.906305 write(8, "@\0\221\0\221\0\221\0\221\0\221\0\263\0\263\0\263\0\242\0\263\0\263\0\263\0Q\0Q\0b\0Q"..., 1024) = 1024
12:17:02.906361 write(8, "Q\0Q\0\242\0b\0\21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 33792) = 33792
12:17:02.924577 gettimeofday({1519233422, 924592}, NULL) = 0
12:17:02.935856 gettimeofday({1519233422, 935870}, NULL) = 0
12:17:02.947417 gettimeofday({1519233422, 947430}, NULL) = 0
12:17:02.947453 write(8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 544) = 544
12:17:02.947523 _llseek(8, 0, [0], SEEK_SET) = 0
12:17:02.947558 read(8, "\1\0\224\10\30\206\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
12:17:02.947616 read(8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 63488) = 63488
12:17:02.947727 read(8, "@\0\221\0\221\0\221\0\221\0\221\0\263\0\263\0\263\0\242\0\263\0\263\0\263\0Q\0Q\0b\0Q"..., 1024) = 1024
12:17:02.947781 read(8, "Q\0Q\0\242\0b\0\21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 33792) = 33792
12:17:02.947864 read(8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 544
12:17:02.948680 close(8) = 0
12:17:02.948713 munmap(0xb7c5c000, 4096) = 0
12:17:02.948751 unlink("/tmp/e0001C6D.tmp") = 0
那么有什么方法可以减少或加快这些呼叫的速度吗?
答案1
RAM 支持的 ext2 文件系统的效率比 ramfs 或 tmpfs 低很多。这就是内核从initrd切换到initramfs的原因之一。尝试将 /tmp 挂载点替换为 tmpfs。