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.