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.