Heute möchten wir über einige der neuesten Updates des Sherlock-Systems [das ist ein leistungsstarker Cluster der Stanford-Universität – Anm. d. Übers.] berichten, die das Auflisten von Dateien in Verzeichnissen mit einer großen Anzahl von Einträgen erheblich beschleunigen.
Im Gegensatz zu gewöhnlichen Artikeln handelt es sich hierbei eher um einen Insiderbericht darüber, wie die regelmäßige Arbeit an Sherlock abläuft, um ihn in bestmöglichem Zustand für unsere Nutzer zu halten. Wir hoffen, in Zukunft mehr solcher Artikel zu veröffentlichen.
Das Auflisten vieler Dateien benötigt Zeit.
Alles begann mit einer Anfrage an den Support von einem Benutzer. Er berichtete über ein Problem, bei dem die Ausführung ls mehrere Minuten in einem Verzeichnis mit über 15.000 Einträgen in $SCRATCH [Verzeichnis für temporäre Dateien – Anm. d. Übers.].
Tausende von Dateien in einem Verzeichnis stellen in der Regel eine Herausforderung für das Dateisystem dar, und das ist definitiv nicht empfehlenswert. Der Benutzer wusste dies und erkannte, dass es nicht ideal ist, erwähnte jedoch, dass das Auflisten auf seinem Laptop 1000 Mal schneller erfolgt als in Sherlock. Natürlich hat uns das getroffen. Deshalb haben wir tiefer gegraben.
Weil ls hübsch aussieht.
Wir haben uns angesehen, was tatsächlich bei ls dem Auflisten eines Verzeichnisses passiert und warum der Prozess so viel Zeit in Anspruch nimmt. In den meisten modernen Distributionen ls wird standardmäßig als ls --color=autoausgeführt, denn jeder mag Farbe.
Aber schöne Farben haben ihren Preis: Für jede Datei ls muss Informationen über den Dateityp, die Berechtigungen, Flags, erweiterte Attribute und Ähnliches eingeholt werden, um die entsprechende Farbe auszuwählen.
Eine der einfachen Lösungen für das Problem besteht darin, die Farben in ls ganz abzuschalten, aber stellen Sie sich das Entsetzen der Nutzer vor. Farbenfrohe Ausgaben dürfen auf keinen Fall entzogen werden, wir sind keine Monster.
Deshalb haben wir tiefer gegraben. ls Färbt die Einträge über die Umgebungsvariable LS_COLORS, die von dircolors(1) basierend auf der Konfigurationsdatei dir_colors(5)gesetzt wird. Ja, (und wenn Sie nichts über die Dateien wissen, do), wird dir_colors Kommen wir näher darauf zu sprechen.
Um herauszufinden, welches der Färbeschemata die Verlangsamung verursacht, haben wir eine experimentelle Umgebung geschaffen:
Um festzustellen, welches der Farbgebungsschemata die Verlangsamung verursacht, haben wir eine experimentelle Umgebung geschaffen:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # Versuch das nicht zu Hause!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s12,7 Sekunden für 10 000 Dateien, nicht sehr gut.
Übrigens, es wird ein Flag benötigt
--color=always: obwohl es sich umwandelt inls --color=auto, aberlser erkennt, wenn er nicht mit einem Terminal verbunden ist (zum Beispiel über eine Pipe oder bei der Umleitung der Ausgabe) und deaktiviert die Farbgebung, wennautogesetzt ist. Ein schlauer Kerl.
Was dauert also so lange? Wir haben es mit strace:
$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% Zeit Sekunden Mikrosekunden/Aufruf Aufrufe Fehler 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 lstat(), 10 000 Aufrufe getxattr() (die alle fehlschlagen, weil in unserer Umgebung keine Attribute vorhanden sind, nach denen ls sucht), 10 000 Aufrufe capget().
Das sollte sicher optimiert werden können.
Attribut capabilities? Nein.
Folgend den Ratschlägen , haben wir versucht, die Attributprüfung zu deaktivieren :
$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% Zeit Sekunden Mikrosekunden/Aufruf Aufrufe Fehler 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 insgesamt
real 0m8.160s
user 0m0.115s
sys 0m0.961s Wow, Beschleunigung auf 8 Sekunden! Wir haben uns von all diesen teuren Aufrufen befreit getxattr(), und die Aufrufe capget() sind auch verschwunden, großartig.
Aber es gibt immer noch diese lästigen Aufrufe lstat(), obwohl…
Wie viele Farben werden benötigt?
Deshalb haben wir uns das genauer angesehen LS_COLORS.
Zuerst haben wir einfach diese Variable 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, wenn die Umgebungsvariable LS_COLORS nicht definiert ist oder nur eines ihrer Elemente fehlt =color:, sie standardmäßig die eingebaute Datenbank verwendet und trotzdem Farben verwendet. Daher, wenn Sie die Farbe für einen bestimmten Dateityp deaktivieren möchten, müssen Sie sie mit =: oder 00 in der Datei DIR_COLORS.
Nach vielen Versuchen und Irrtümern haben wir die Suche auf Folgendes eingegrenzt:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00was als
LS_COLORS='ex=00:su=00:sg=00:ca=00:' das bedeutet: färbe Dateien nicht nach Attributen , sondern nach Bits , auch nicht nach .
Wir beschleunigen ls
Und wenn keine dieser Prüfungen durchgeführt wird, verschwinden die Aufrufe, und es ist nun ganz anders: lstat() $ export LS_COLORS='ex=00:su=00:sg=00:ca=00:' $ time strace -c ls --color=always $SCRATCH/dont | wc -l 10000 % Zeit Sekunden Mikrosekunden/Aufruf Aufrufe Fehler 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 totalreal 0m0.337s user 0m0.032s sys 0m0.029s
0,3 Sekunden für eine Liste von 10.000 Dateien, Rekord.Konfigurieren wir Sherlock
Von 13 Sekunden mit den Standardeinstellungen auf 0,3 Sekunden mit einer kleinen Anpassung
bedeutet eine 40-fache Beschleunigung aufgrund des Fehlens LS_COLORS und gefärbten ausführbaren Dateien. Nicht so ein großer Verlust. setuid / setgid und die farbigen ausführbaren Dateien. Nicht so ein großer Verlust.
Natürlich ist das jetzt in Sherlock für jeden Benutzer eingestellt.
Wenn Sie die Farbcodierung jedoch zurückbringen möchten, können Sie einfach zu den Standardeinstellungen zurückkehren:
$ unset LS_COLORS Aber bei Verzeichnissen mit vielen Dateien machen Sie besser eine Kaffeepause, während es läuft. ls.
Quelle: habr.com
