Heute möchten wir über einige der neuesten Updates des Sherlock-Systems sprechen [dies ist ein Hochleistungscluster an der Stanford University – ca. trans.], was das Auflisten von Dateien in Verzeichnissen mit vielen Einträgen erheblich beschleunigt.
Im Gegensatz zu normalen Artikeln ist dies eher ein Insiderbericht darüber, wie wir regelmäßig an Sherlock arbeiten, damit es für unsere Benutzer optimal läuft. Wir hoffen, in Zukunft weitere Artikel dieser Art veröffentlichen zu können.
Das Auflisten vieler Dateien nimmt Zeit in Anspruch
Alles begann mit einer technischen Supportfrage eines Benutzers. Er meldete das Problem, dass die Hinrichtung ls
dauert in einem Verzeichnis mit über 15 Einträgen ein paar Minuten $SCRATCH
[Verzeichnis für temporäre Dateien – ca. Fahrbahn].
Tausende Dateien in einem Verzeichnis stellen meist eine Belastung für das Dateisystem dar und sind definitiv nicht zu empfehlen. Der Benutzer wusste das und gab zu, dass es nicht gut war, erwähnte jedoch, dass die Auflistung auf seinem Laptop 1000-mal schneller war als bei Sherlock. Das hat uns natürlich wehgetan. Also schauten wir tiefer.
Weil ls gut aussieht
Wir haben uns angeschaut, was es tatsächlich leistet ls
beim Auflisten eines Verzeichnisses und warum der Vorgang so lange dauert. Auf den meisten modernen Distributionen ls
Standardmäßig läuft es als ls --color=auto
, weil die Farben jedem gefallen.
Aber schöne Farben haben ihren Preis: für jede Datei ls
muss Informationen über den Dateityp, seine Berechtigungen, Flags, erweiterten Attribute und dergleichen einholen, um die entsprechende Farbe auszuwählen.
Eine einfache Lösung für das Problem besteht darin, die Farbe in ls ganz zu deaktivieren, aber stellen Sie sich die Empörung der Benutzer vor. Auf keinen Fall sollte man die Farbausgabe wegnehmen, wir sind keine Monster.
Also schauten wir tiefer. ls
Farbeinträge über Umgebungsvariable LS_COLORS
, die eingestellt ist dircolors(1)
basierend auf der Konfigurationsdatei dir_colors(5)
. Ja,
Lass uns genauer hinschauen
Um festzustellen, welches Farbschema die 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 Dateien, nicht sehr gut.
Übrigens brauchen wir eine Flagge
--color=always
: obwohl er sich umdrehtls --color=auto
Aberls
erkennt, wenn es nicht mit einem Terminal verbunden ist (z. B. per Pipe oder mit Ausgabeumleitung) und deaktiviert die Farbgebung, wenn es auf eingestellt istauto
. Schlauer Typ.
Warum dauert es so lange? Wir schauten 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 Anrufe lstat()
, 10 Anrufe getxattr()
(die alle fehlschlagen, weil unsere Umgebung nicht über die Attribute verfügt, nach denen ls sucht), 10 Aufrufe capget()
.
Sicherlich lässt sich das optimieren.
Attribut „Fähigkeiten“? Nein
Befolgen Sie den Rat
$ 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, bis zu 8 Sekunden Beschleunigung! Wir haben all diese teuren Anrufe abgeschafft getxattr()
und Herausforderungen capget()
ist auch verschwunden, super.
Aber es gibt immer noch diese nervigen Anrufe lstat()
, Obwohl…
Wie viele Blumen brauchen Sie?
Deshalb haben wir genauer hingeschaut LS_COLORS
.
Zuerst haben wir diese Variable einfach deaktiviert:
$ 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
Was!?! Immer noch 13 Sekunden?
Es stellt sich heraus, dass die Umgebungsvariable LS_COLORS
nur eines seiner Elemente ist nicht definiert oder fehlt <type>=color:
, verwendet es standardmäßig die integrierte Datenbank und verwendet weiterhin Farben. Wenn Sie also die Einfärbung für einen bestimmten Dateityp deaktivieren möchten, müssen Sie sie mit überschreiben <type>=:
oder <type> 00
im Ordner DIR_COLORS
.
Nach vielen Versuchen und Irrtümern haben wir unsere Suche auf Folgendes eingegrenzt:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
was geschrieben wird als
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
Das bedeutet: Dateien nicht nach Attributen einfärben.
, weder von
Wir beschleunigen ls
Und wenn Sie keine dieser Prüfungen durchführen, dann rufen Sie an lstat()
verschwinden, 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 Dateien, ein Rekord.
Sherlock einrichten
Von 13 Sekunden mit Standardeinstellungen auf 0,3 Sekunden mit geringfügigen Anpassungen LS_COLORS
bedeutet eine 40-fache Beschleunigung aufgrund der Abwesenheit setuid
/ setgid
und farbige ausführbare Dateien. Kein so großer Verlust.
Natürlich wird dies jetzt in Sherlock für jeden Benutzer konfiguriert.
Wenn Sie die Farbgebung jedoch wiederherstellen möchten, können Sie einfach zu den Standardeinstellungen zurückkehren:
$ unset LS_COLORS
Stellen Sie jedoch sicher, dass bei Verzeichnissen mit vielen Dateien der Kaffee während des Betriebs zubereitet wird ls
.
Source: habr.com