Lorsqu'une variable d'environnement accélère le processus de 40 fois

Aujourd'hui, nous voulons parler de certaines des dernières mises à jour du système Sherlock [il s'agit d'un cluster de haute performance à l'Université de Stanford - env. par.], ce qui accélère considérablement la liste des fichiers dans les répertoires avec un grand nombre d'entrées.

Contrairement aux articles réguliers, il s'agit davantage d'un rapport d'initié sur la façon dont le travail régulier sur Sherlock se déroule afin de le maintenir de la meilleure façon possible pour nos utilisateurs. Nous espérons publier davantage d'articles de ce type à l'avenir.

La liste de nombreux fichiers prend du temps


Tout a commencé par une question d'assistance technique de l'utilisateur. Il a signalé un problème selon lequel l'exécution de ls prenait plusieurs minutes dans un répertoire contenant plus de 15 000 entrées dans le répertoire $SCRATCH [pour les fichiers temporaires - env. trans.].

Des milliers de fichiers dans un répertoire créent généralement des difficultés pour le système de fichiers et ce n'est certainement pas recommandé. L'utilisateur le savait et a admis que ce n'était pas bon, mais a mentionné que l'inscription sur son ordinateur portable était 1000 fois plus rapide que dans Sherlock. Bien sûr, cela nous a frappés. Par conséquent, nous avons regardé plus profondément.

Parce que ls est magnifique


Nous avons examiné ce que ls fait réellement lors de l'inscription d'un répertoire et pourquoi le processus prend autant de temps. Sur la plupart des distributions modernes, ls défaut ls --color=auto , car tout le monde aime la couleur.

Mais les belles couleurs ont un prix: pour chaque fichier, ls doit obtenir des informations sur le type de fichier, ses résolutions, ses indicateurs, ses attributs avancés, etc., afin de sélectionner la couleur appropriée.

L'une des solutions simples au problème est de désactiver complètement la couleur dans ls, mais imaginez l'indignation des utilisateurs. En aucun cas vous ne pouvez prendre la sortie couleur, nous ne sommes pas des monstres.

Par conséquent, nous avons regardé plus profondément. ls peint les enregistrements via la LS_COLORS environnement LS_COLORS , que dircolors(1) définit en fonction du fichier de configuration dir_colors(5) . Oui, l' exécutable lit le fichier de configuration pour créer une variable d'environnement, que ls utilise ensuite (et si vous ne connaissez pas les fichiers door (do), alors dir_colors fonctionnera , quoi qu'il arrive).

Nous comprendrons plus en détail


Pour déterminer lequel des schémas de colorisation provoque un 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, pas très bon.
Soit dit en passant, nous avons besoin du drapeau --color=always : bien qu'il se transforme en ls --color=auto , mais ls détecte lorsqu'il n'est pas connecté au terminal (par exemple, via un canal ou avec une redirection de sortie) et désactive la coloration s'il est défini sur auto . Mec intelligent.
Alors, qu'est-ce qui prend si longtemps? 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 [...] 

Wow: 10 000 appels à lstat() , 10 000 appels à getxattr() (ce que tout le monde échoue car dans notre environnement il n'y a pas d'attributs que ls recherche), 10 000 appels à capget() .

Cela peut certainement être optimisé.

Attribut Capacités Non


En suivant les conseils d'un bug d'il y a 10 ans , nous avons essayé de désactiver la vérification de l'attribut capacités :

 $ 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, accélération jusqu'à 8 secondes! Nous nous sommes débarrassés de tous ces appels getxattr() coûteux, et les capget() également disparu, capget() .

Mais ces appels ennuyeux à lstat() toujours restés, bien que ...

De combien de fleurs avez-vous besoin?


Par conséquent, nous avons examiné LS_COLORS plus en détail.

Tout d'abord, ils ont 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: ou = 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
 10 000

 réel 0m13.037s
 utilisateur 0m0.077s
 sys 0m1.092s 

Quoi!?! Encore 13 secondes?

Il s'avère que lorsque la LS_COLORS environnement LS_COLORS pas définie ou si un seul de ses éléments <type>=color: manquant, il utilise la base de données intégrée par défaut et utilise toujours des couleurs. Par conséquent, si vous souhaitez désactiver la coloration pour un type de fichier spécifique, vous devez le 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 

ce qui est écrit

 LS_COLORS='ex=00:su=00:sg=00:ca=00:' 

Cela signifie: ne colorez pas les fichiers par les capacités atrubut, par les bits setuid/setgid ou par le drapeau exécutable .

Accélérer ls


Et si vous n'effectuez aucune de ces vérifications, les appels à lstat() disparaissent, 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 un petit paramètre, LS_COLORS signifie une accélération de 40 fois en raison du manque de fichiers exécutables setuid / setgid et colorés. Pas une grosse perte.

Bien sûr, cela est maintenant configuré dans Sherlock pour chaque utilisateur.

Mais si vous souhaitez retourner la coloration, vous pouvez simplement revenir aux paramètres par défaut:

 $ unset LS_COLORS 

Mais alors sur les répertoires avec un grand nombre de fichiers, assurez-vous de faire du café pendant que ls fonctionne.

Source: https://habr.com/ru/post/fr450806/


All Articles