今天,我们想谈谈Sherlock系统的一些最新更新[这是斯坦福大学的高性能集群-大约是。 per。],大大加快了具有大量条目的目录中文件的列出。
与常规文章不同的是,这更多是内部调查报告,内容是有关Sherlock的常规工作如何进行的,以便以最佳方式维护用户。 我们希望将来发布更多此类文章。
列出许多文件需要时间
一切都始于用户提出的技术支持问题。 他报告了一个问题,即在目录
$SCRATCH
有超过15,000个条目的目录中运行
ls
花费几分钟时间。 跨]。
一个目录中的成千上万个文件通常会给文件系统带来麻烦,因此绝对不建议这样做。 用户知道这一点,并承认这不好,但是他提到在笔记本电脑上的挂牌速度比Sherlock快1000倍。 当然,它打击了我们。 因此,我们看起来更深入。
因为ls看起来很漂亮
我们查看了
ls
列出目录时的实际作用,以及该过程花了这么长时间的原因。 在大多数现代发行版中,
ls
默认为
ls --color=auto
,因为每个人都喜欢这种颜色。
但是漂亮的颜色是有代价的:对于每个文件,
ls
需要获取有关文件类型,其权限,标志,高级属性等的信息,以便选择适当的颜色。
解决此问题的简单方法之一是完全禁用ls,但请想象一下用户的愤怒。 在任何情况下,您都不能输出颜色,我们不是怪物。
因此,我们看起来更深入。
ls
通过
LS_COLORS
环境
LS_COLORS
绘制记录,该
LS_COLORS
是
dircolors(1)
根据
dir_colors(5)
配置文件设置的。 是的,
可执行文件读取配置文件以创建一个ls然后使用的环境变量 (如果您不知
道门 (do)文件,则dir_colors
可以使用 ,无论如何)。
我们将更详细地了解
为了确定哪种着色方案会导致速度降低,我们创建了一个实验环境:
$ 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
10,000个文件需要12.7秒,不是很好。顺便说一句,我们需要标志--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,000次调用
lstat()
,10,000次调用
getxattr()
(每个人都失败了,因为在我们的环境中ls不会寻找属性),10,000次调用
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:或= 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:
$未设置LS_COLORS
$ echo $ LS_COLORS
$ time ls --color =总是$ SCRATCH / dont | wc -l
10,000
真正的0m13.037s
用户0m0.077s
sys 0m1.092s
什么!?! 还是13秒?
事实证明,当
LS_COLORS
环境
LS_COLORS
或仅缺少其元素之一
<type>=color:
,默认情况下它将使用内置数据库,并且仍使用颜色。 因此,如果要禁用特定文件类型的着色,则需要在
DIR_COLORS
文件中使用
<type>=:
或
<type> 00
覆盖它。
经过大量的试验和错误,我们将搜索范围缩小到:
EXEC 00 SETUID 00 SETGID 00 CAPABILITY 00
什么写成
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
这意味着:请勿通过
功能 atrubut,
setuid/setgid
位或
可执行标志来为
文件着色。
加速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
在10,000个文件的列表上记录了0.3秒。
配置夏洛克
从默认设置的13秒到小设置的0.3秒,由于缺少
setuid
/
setgid
和彩色的可执行文件,
LS_COLORS
意味着40倍的加速。 没有那么大的损失。
当然,现在在Sherlock中为每个用户配置了此功能。
但是,如果要返回颜色,则可以返回默认设置:
$ unset LS_COLORS
但是,在具有大量文件的目录上,请确保在
ls
工作时冲泡咖啡。