Wenn eine Umgebungsvariable den Prozess um das 40-fache beschleunigt

Heute möchten wir über einige der neuesten Updates des Sherlock-Systems sprechen [dies ist ein Hochleistungscluster an der Stanford University - ca. per.], was die Auflistung von Dateien in Verzeichnissen mit einer großen Anzahl von Einträgen erheblich beschleunigt.

Im Gegensatz zu regulären Artikeln ist dies eher ein Insiderbericht darüber, wie Sherlock regelmäßig arbeitet, um es für unsere Benutzer bestmöglich zu erhalten. Wir hoffen, in Zukunft weitere solche Artikel veröffentlichen zu können.

Das Auflisten vieler Dateien braucht Zeit


Alles begann mit einer Frage des technischen Supports des Benutzers. Er berichtete über ein Problem, dass das Ausführen von ls in einem Verzeichnis mit mehr als 15.000 Einträgen in $SCRATCH [Verzeichnis für temporäre Dateien - ca. trans.].

Tausende von Dateien in einem Verzeichnis verursachen normalerweise Schwierigkeiten für das Dateisystem, und dies wird definitiv nicht empfohlen. Der Benutzer wusste dies und gab zu, dass es nicht gut war, erwähnte jedoch, dass die Auflistung auf seinem Laptop 1000-mal schneller war als in Sherlock. Natürlich hat es uns getroffen. Deshalb haben wir tiefer geschaut.

Weil es schön aussieht


Wir haben uns angesehen, was ls beim Auflisten eines Verzeichnisses tatsächlich tut und warum der Vorgang so lange dauert. Bei den meisten modernen Distributionen ist ls standardmäßig ls --color=auto , da jeder die Farbe mag.

Aber schöne Farben haben ihren Preis: Für jede Datei muss sie Informationen über den Dateityp, ihre Berechtigungen, Flags, erweiterten Attribute und dergleichen erhalten, um die entsprechende Farbe auszuwählen.

Eine der einfachen Lösungen für das Problem besteht darin, die Farbe in ls insgesamt zu deaktivieren, sich aber die Empörung der Benutzer vorzustellen. In keinem Fall können Sie die Farbausgabe übernehmen, wir sind keine Monster.

Deshalb haben wir tiefer geschaut. ls malt die Datensätze über die Umgebungsvariable LS_COLORS , die dircolors(1) basierend auf der Konfigurationsdatei dir_colors(5) . Ja, die ausführbare Datei liest die Konfigurationsdatei, um eine Umgebungsvariable zu erstellen, die dann verwendet wird (und wenn Sie nichts über die Door (do) ​​-Dateien wissen , funktioniert dir_colors, egal was passiert).

Wir werden es genauer verstehen


Um festzustellen, welches der Kolorierungsschemata eine Verlangsamung verursacht, haben wir eine experimentelle Umgebung erstellt:

 $ 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 Sekunden für 10.000 Dateien, nicht sehr gut.
Übrigens brauchen wir das Flag --color=always : Obwohl es sich zu ls --color=auto dreht, erkennt ls wenn es nicht mit dem Terminal verbunden ist (z. B. über einen Kanal oder mit Ausgangsumleitung) und deaktiviert die Farbgebung, wenn es auf auto . Kluger Kerl.
Was dauert so lange? Wir haben mit 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 Aufrufe von lstat() , 10.000 Aufrufe von getxattr() (was jeder fehlschlägt, weil es in unserer Umgebung keine Attribute gibt, nach denen ls sucht), 10.000 Aufrufe von capget() .

Dies kann sicherlich optimiert werden.

Capabilities-Attribut Nein


Nach dem Rat eines Fehlers vor 10 Jahren haben wir versucht, die Überprüfung des Fähigkeitsattributs zu deaktivieren:

 $ 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, Beschleunigung bis zu 8 Sekunden! Wir haben all diese teuren getxattr() -Aufrufe getxattr() , und die capget() -Aufrufe sind ebenfalls verschwunden, großartig.

lstat() blieben diese nervigen Aufrufe von lstat() bestehen ...

Wie viele Blumen brauchst du?


Daher haben wir LS_COLORS genauer untersucht.

Zuerst haben sie diese Variable einfach ausgeschaltet:

  $ 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: oder = 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 = immer $ SCRATCH / dont |  wc -l
 10.000

 echte 0m13.037s
 Benutzer 0m0.077s
 sys 0m1.092s 

Was!?! Noch 13 Sekunden?

Es stellt sich heraus, dass die Umgebungsvariable LS_COLORS , wenn sie nicht definiert ist oder nur eines ihrer Elemente <type>=color: fehlt, standardmäßig die integrierte Datenbank verwendet und weiterhin Farben verwendet. Wenn Sie die Farbgebung für einen bestimmten Dateityp deaktivieren möchten, müssen Sie diese daher in der Datei DIR_COLORS mit <type>=: oder <type> 00 DIR_COLORS .

Nach vielen Versuchen und Irrtümern haben wir unsere Suche auf Folgendes beschränkt:

 EXEC 00 SETUID 00 SETGID 00 CAPABILITY 00 

was geschrieben steht als

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

Dies bedeutet: Färben Sie die Dateien weder nach den Funktionen atrubut noch nach den setuid/setgid Bits oder nach dem ausführbaren Flag .

Beschleunigung ls


Und wenn Sie keine dieser Überprüfungen durchführen, verschwinden die Aufrufe von lstat() , und jetzt ist es eine ganz andere Sache:

 $ 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 Sekunden auf einer Liste von 10.000 Dateien, ein Datensatz.

Konfigurieren Sie Sherlock


Von 13 Sekunden mit Standardeinstellungen bis 0,3 Sekunden mit einer kleinen Einstellung bedeutet LS_COLORS eine 40-fache Beschleunigung aufgrund des Fehlens von setuid / setgid und farbigen ausführbaren Dateien. Kein so großer Verlust.

Natürlich ist dies jetzt in Sherlock für jeden Benutzer konfiguriert.

Wenn Sie jedoch die Farbe zurückgeben möchten, können Sie einfach zu den Standardeinstellungen zurückkehren:

 $ unset LS_COLORS 

Stellen Sie dann in Verzeichnissen mit einer großen Anzahl von Dateien sicher, dass Sie Kaffee ls , während ls arbeitet.

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


All Articles