Avui volem parlar d'algunes de les últimes actualitzacions del sistema Sherlock [es tracta d'un clúster d'alt rendiment a la Universitat de Stanford: aprox. trans.], que acceleren significativament la llista de fitxers en directoris amb un gran nombre d'entrades.
A diferència dels articles habituals, aquest és més un informe d'informació privilegiada sobre com treballem regularment a Sherlock per mantenir-lo funcionant al màxim per als nostres usuaris. Esperem poder publicar més articles com aquest en el futur.
Llistar molts fitxers requereix temps
Tot va començar amb una pregunta d'assistència tècnica d'un usuari. Va informar del problema que l'execució ls
triga uns minuts en un directori amb més de 15 entrades $SCRATCH
[directori per a fitxers temporals - aprox. carril].
Milers de fitxers en un directori solen suposar una càrrega per al sistema de fitxers i definitivament no es recomana. L'usuari ho sabia i va admetre que no era bo, però va esmentar que la llista era 1000 vegades més ràpida al seu ordinador portàtil que Sherlock. Això sí, això ens va fer mal. Així que vam mirar més a fons.
Perquè es veu bé
Vam mirar què fa realment ls
en llistar un directori i per què el procés triga tant. A la majoria de distribucions modernes ls
per defecte s'executa com ls --color=auto
, perquè a tothom li agraden els colors.
Però els colors bonics tenen un preu: per a cada fitxer ls
ha d'obtenir informació sobre el tipus de fitxer, els seus permisos, banderes, atributs ampliats i similars per seleccionar el color adequat.
Una solució senzilla al problema és desactivar el color a ls per complet, però imagineu-vos la indignació dels usuaris. En cap cas hauríeu de treure la sortida del color, no som monstres.
Així que vam mirar més a fons. ls
entrades de colors mitjançant variable d'entorn LS_COLORS
, que està establert dircolors(1)
basat en el fitxer de configuració dir_colors(5)
... Sí,
Fem una ullada més de prop
Per determinar quina combinació de colors provoca la desacceleració, hem creat un entorn experimental:
$ 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 segons per a 10 fitxers, no molt bo.
Per cert, necessitem una bandera
--color=always
: encara que recorre als --color=auto
Sinóls
detecta quan no està connectat a un terminal (per exemple, per canonada o amb redirecció de sortida) i desactiva el color si s'estableix aauto
. Paio intel·ligent.
Aleshores, què triga tant? Hem mirat amb 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
[...]
Wow: 10 trucades lstat()
, 10 trucades getxattr()
(que fallen tots perquè el nostre entorn no té els atributs que ls busca), 10 trucades capget()
.
Segurament això es pot optimitzar.
Atribut de capacitats? No
Seguint consells
$ 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
Vaja, fins a 8 segons d'acceleració! Ens vam desfer de totes aquelles trucades cares getxattr()
, i reptes capget()
també va desaparèixer, genial.
Però encara hi ha aquestes trucades molestes lstat()
, tot i que…
Quantes flors necessites?
Per tant, hem fet una ullada més de prop LS_COLORS
.
Primer simplement vam desactivar aquesta variable:
$ 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
Què!?! Encara queden 13 segons?
Resulta que quan la variable d'entorn LS_COLORS
només un dels seus elements no està definit o falta <type>=color:
, utilitza la base de dades integrada per defecte i encara utilitza colors. Per tant, si voleu desactivar la coloració per a un tipus de fitxer determinat, heu de substituir-lo <type>=:
o <type> 00
a l'arxiu DIR_COLORS
.
Després de moltes proves i errors, hem reduït la nostra cerca a això:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
que s'escriu com
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
Això vol dir: no acolorir els fitxers per atribut.
, ni per
Accelerem ls
I si no feu cap d'aquestes comprovacions, truqueu lstat()
desaparèixer, i ara és una qüestió completament diferent:
$ 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 segons en una llista de 10 fitxers, un rècord.
Configurant Sherlock
Des de 13 segons amb la configuració predeterminada fins a 0,3 segons amb ajustos menors LS_COLORS
significa una acceleració de 40 vegades a causa de l'absència setuid
/ setgid
i fitxers executables de colors. No és una pèrdua tan gran.
Per descomptat, això ara està configurat a Sherlock per a cada usuari.
Però si voleu tornar el color, simplement podeu tornar a la configuració predeterminada:
$ unset LS_COLORS
Però després, als directoris amb molts fitxers, assegureu-vos de preparar cafè mentre s'està executant ls
.
Font: www.habr.com