Aujourd'hui, nous voulons parler de certaines des dernières mises à jour du système Sherlock [il s'agit d'un cluster hautes performances de l'Université de Stanford - env. trans.], ce qui accélère considérablement le référencement des fichiers dans des répertoires comportant un grand nombre d'entrées.
Contrairement aux articles réguliers, il s'agit plutôt d'un rapport d'initié sur la façon dont nous travaillons régulièrement sur Sherlock pour qu'il fonctionne au mieux pour nos utilisateurs. Nous espérons publier davantage d’articles comme celui-ci à l’avenir.
Lister de nombreux fichiers prend du temps
Tout a commencé avec une question d'assistance technique d'un utilisateur. Il a signalé le problème que l'exécution ls
prend quelques minutes dans un répertoire contenant plus de 15 000 entrées $SCRATCH
[répertoire pour les fichiers temporaires - env. voie].
Des milliers de fichiers dans un répertoire représentent généralement une charge pour le système de fichiers et ne sont absolument pas recommandés. L'utilisateur le savait et a admis que ce n'était pas bon, mais a mentionné que le listing était 1000 fois plus rapide sur son ordinateur portable que sur Sherlock. Bien sûr, cela nous a blessé. Nous avons donc cherché plus profondément.
Parce que ça a l'air sympa
Nous avons regardé ce que ça fait réellement ls
lors de l'inscription d'un répertoire et pourquoi le processus prend si longtemps. Sur la plupart des distributions modernes ls
par défaut, il fonctionne comme ls --color=auto
, parce que tout le monde aime les couleurs.
Mais les belles couleurs ont un prix : pour chaque fichier ls
doit obtenir des informations sur le type de fichier, ses autorisations, ses indicateurs, ses attributs étendus, etc. afin de sélectionner la couleur appropriée.
Une solution simple au problème consiste à désactiver complètement la couleur dans ls, mais imaginez l'indignation des utilisateurs. Vous ne devez en aucun cas supprimer la sortie couleur, nous ne sommes pas des monstres.
Nous avons donc cherché plus profondément. ls
entrées de couleurs via une variable d'environnement LS_COLORS
, qui est fixé dircolors(1)
basé sur le fichier de configuration dir_colors(5)
... Oui,
Regardons de plus près
Pour déterminer quelle palette de couleurs provoque le ralentissement, nous avons créé un environnement expérimental :
$ 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 secondes pour 10 000 fichiers, ce qui n'est pas très bon.
Au fait, nous avons besoin d'un drapeau
--color=always
: bien qu'il se tourne versls --color=auto
maisls
détecte quand il n'est pas connecté à un terminal (par exemple par tuyau ou avec redirection de sortie) et désactive la coloration s'il est défini surauto
. Gars intelligent.
Alors, qu'est-ce qui prend autant de temps ? Nous avons regardé avec 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
[...]
Waouh : 10 000 appels lstat()
, 10 000 appels getxattr()
(qui échouent tous parce que notre environnement n'a pas les attributs recherchés par ls), 10 000 appels capget()
.
Cela peut sûrement être optimisé.
Attribut de capacités ? Non
Suite des conseils
$ 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
Wow, jusqu'à 8 secondes d'accélération ! Nous nous sommes débarrassés de tous ces appels coûteux getxattr()
, et les défis capget()
disparu aussi, super.
Mais il y a toujours ces appels ennuyeux lstat()
, Bien que…
De combien de fleurs avez-vous besoin ?
Nous avons donc regardé de plus près LS_COLORS
.
Nous avons d’abord simplement désactivé cette 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
Quoi!?! Encore 13 secondes ?
Il s'avère que lorsque la variable d'environnement LS_COLORS
un seul de ses éléments n'est pas défini ou est manquant <type>=color:
, il utilise la base de données intégrée par défaut et utilise toujours les couleurs. Donc, si vous souhaitez désactiver la colorisation pour un certain type de fichier, vous devez la remplacer par <type>=:
ou <type> 00
dans le fichier DIR_COLORS
.
Après de nombreux essais et erreurs, nous avons limité notre recherche à ceci :
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
qui s'écrit comme
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
Cela signifie : ne coloriez pas les fichiers par attribut.
, ni par
Nous accélérons ls
Et si vous ne faites aucune de ces vérifications, alors appelez lstat()
disparaître, et maintenant c'est une tout autre affaire :
$ 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 seconde sur une liste de 10 000 fichiers, un record.
Configurer Sherlock
De 13 secondes avec les paramètres par défaut à 0,3 seconde avec des ajustements mineurs LS_COLORS
signifie une accélération de 40 fois en raison de l'absence setuid
/ setgid
et des fichiers exécutables colorés. Ce n’est pas une si grosse perte.
Bien entendu, cela est désormais configuré dans Sherlock pour chaque utilisateur.
Mais si vous souhaitez restituer la coloration, vous pouvez simplement revenir aux paramètres par défaut :
$ unset LS_COLORS
Mais dans les répertoires contenant beaucoup de fichiers, assurez-vous de préparer du café pendant son exécution. ls
.
Source: habr.com