今天我们想谈谈 Sherlock 系统的一些最新更新[这是斯坦福大学的一个高性能集群 - 大约。 trans.],这显着加快了列出具有大量条目的目录中的文件的速度。
与普通文章不同,这更多的是内部人士的报告,介绍我们如何定期开发 Sherlock,以使其为用户保持最佳运行状态。 我们希望将来发表更多这样的文章。
列出许多文件需要时间
这一切都始于用户的技术支持问题。 他报告了执行的问题 ls
在包含超过 15 个条目的目录中需要几分钟 $SCRATCH
[临时文件目录 - 大约。 车道]。
一个目录中的数千个文件通常会对文件系统造成负担,绝对不建议这样做。 用户知道这一点并承认这不好,但提到在他的笔记本电脑上列出的速度比 Sherlock 快 1000 倍。 当然,这伤害了我们。 所以我们看得更深入。
因为ls看起来不错
我们研究了它的实际作用 ls
列出目录时,以及为什么该过程需要这么长时间。 在大多数现代发行版上 ls
默认情况下它运行为 ls --color=auto
,因为每个人都喜欢这些颜色。
但美丽的色彩是有代价的:对于每个文件 ls
必须获取有关文件类型、其权限、标志、扩展属性等的信息,以便选择适当的颜色。
解决这个问题的一个简单方法是完全禁用 ls 中的颜色,但想象一下用户的愤怒吧。 在任何情况下都不应该取消颜色输出,我们不是怪物。
所以我们看得更深入。 ls
通过环境变量的颜色条目 LS_COLORS
,设置为 dircolors(1)
基于配置文件 dir_colors(5)
... 是,
让我们仔细看看
为了确定哪种配色方案导致速度变慢,我们创建了一个实验环境:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # don't try this at home!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s
12,7 个文件需要 10 秒,不太好。
顺便说一句,我们需要一个标志
--color=always
: 虽然他转向ls --color=auto
但ls
检测何时未连接到终端(例如通过管道或使用输出重定向)并禁用着色(如果设置为)auto
。 聪明的家伙。
那么什么需要这么长时间呢? 我们看着 strace
:
$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
44.21 0.186617 19 10000 lstat
42.60 0.179807 18 10000 10000 getxattr
12.19 0.051438 5 10000 capget
0.71 0.003002 38 80 getdents
0.07 0.000305 10 30 mmap
0.05 0.000217 12 18 mprotect
0.03 0.000135 14 10 read
0.03 0.000123 11 11 open
0.02 0.000082 6 14 close
[...]
哇:10 个电话 lstat()
, 10 次通话 getxattr()
(全部失败,因为我们的环境没有 ls 正在寻找的属性),10 次调用 capget()
.
当然,这可以优化。
能力属性? 没有
$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:/)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
98.95 0.423443 42 10000 lstat
0.78 0.003353 42 80 getdents
0.04 0.000188 10 18 mprotect
0.04 0.000181 6 30 mmap
0.02 0.000085 9 10 read
0.02 0.000084 28 3 mremap
0.02 0.000077 7 11 open
0.02 0.000066 5 14 close
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.427920 10221 6 total
real 0m8.160s
user 0m0.115s
sys 0m0.961s
哇,高达8秒的加速! 我们摆脱了所有那些昂贵的电话 getxattr()
和挑战 capget()
也消失了,太好了。
但仍然有这些烦人的电话 lstat()
, 虽然…
你需要多少朵花?
因此,我们仔细观察了 LS_COLORS
.
首先我们简单地禁用这个变量:
$ echo $LS_COLORS rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: $ unset LS_COLORS $ echo $LS_COLORS $ time ls --color=always $SCRATCH/dont | wc -l 10000 real 0m13.037s user 0m0.077s sys 0m1.092s
什么!?! 还有13秒吗?
事实证明,当环境变量 LS_COLORS
只有一个元素未定义或缺失 <type>=color:
,它默认使用内置数据库并且仍然使用颜色。 因此,如果您想禁用某种文件类型的着色,则需要使用以下命令覆盖它 <type>=:
или <type> 00
在文件中 DIR_COLORS
.
经过大量的试验和错误,我们将搜索范围缩小到:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
写成
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
这意味着:不要按属性为文件着色。
,也不由
我们加快速度 ls
如果您不执行任何这些检查,则调用 lstat()
消失了,现在是完全不同的事情了:
$ export LS_COLORS='ex=00:su=00:sg=00:ca=00:'
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
63.02 0.002865 36 80 getdents
8.10 0.000368 12 30 mmap
5.72 0.000260 14 18 mprotect
3.72 0.000169 15 11 open
2.79 0.000127 13 10 read
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.004546 221 6 total
real 0m0.337s
user 0m0.032s
sys 0m0.029s
0,3秒列出10个文件的列表,创纪录。
设置夏洛克
从默认设置的 13 秒到微调后的 0,3 秒 LS_COLORS
意味着由于不存在而产生 40 倍的加速度 setuid
/ setgid
和彩色可执行文件。 没有那么大的损失。
当然,现在这是在 Sherlock 中为每个用户配置的。
但如果你想恢复颜色,你可以简单地恢复到默认设置:
$ unset LS_COLORS
但在有很多文件的目录上,一定要在运行时煮咖啡 ls
.
来源: habr.com