Wanneer een omgevingsvariabele het proces 40 keer versnelt

Vandaag willen we het hebben over enkele van de nieuwste updates van het Sherlock-systeem [dit is een krachtig cluster aan de Stanford University - ca. trans.], wat het weergeven van bestanden in mappen met een groot aantal vermeldingen aanzienlijk versnelt.

In tegenstelling tot reguliere artikelen is dit meer een insiderrapport over hoe we regelmatig aan Sherlock werken om het op zijn best te laten werken voor onze gebruikers. We hopen in de toekomst meer van dit soort artikelen te publiceren.

Het weergeven van veel bestanden kost tijd

Het begon allemaal met een technische ondersteuningsvraag van een gebruiker. Hij meldde het probleem van de executie ls duurt een paar minuten in een directory met meer dan 15 vermeldingen $SCRATCH [directory voor tijdelijke bestanden - ca. rijbaan].

Duizenden bestanden in één map vormen doorgaans een belasting voor het bestandssysteem en dit wordt zeker niet aanbevolen. De gebruiker wist dit en gaf toe dat het niet goed was, maar zei dat de vermelding op zijn laptop 1000 keer sneller was dan Sherlock. Natuurlijk heeft dit ons pijn gedaan. Dus gingen we dieper kijken.

Omdat het er leuk uitziet

We hebben gekeken naar wat het precies doet ls bij het vermelden van een directory, en waarom het proces zo lang duurt. Op de meeste moderne distributies ls standaard draait het als ls --color=auto, omdat iedereen van de kleuren houdt.

Maar mooie kleuren hebben een prijs: voor elk bestand ls moet informatie verkrijgen over het bestandstype, de machtigingen, vlaggen, uitgebreide attributen en dergelijke om de juiste kleur te selecteren.

Een eenvoudige oplossing voor het probleem is om kleur in ls helemaal uit te schakelen, maar stel je de verontwaardiging van de gebruikers eens voor. Je mag in geen geval de kleurweergave wegnemen, wij zijn geen monsters.

Dus gingen we dieper kijken. ls kleureninvoer via omgevingsvariabele LS_COLORS, die is ingesteld dircolors(1) gebaseerd op configuratiebestand dir_colors(5). Ja, het uitvoerbare bestand leest het configuratiebestand om een ​​omgevingsvariabele te maken, die ls vervolgens gebruikt (en als je niets van bestanden weet deur (do), en vervolgens dir_colors zal werken, Ondanks alles).

Laten we dat eens van dichterbij bekijken

Om te bepalen welk kleurenschema de vertraging veroorzaakt, hebben we een experimentele omgeving gemaakt:

$ 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 seconden voor 10 bestanden, niet erg goed.

We hebben trouwens een vlag nodig --color=always: hoewel hij zich omdraait ls --color=autoMaar ls detecteert wanneer het niet is aangesloten op een terminal (bijvoorbeeld via een pijpleiding of met uitgangsomleiding) en schakelt het kleuren uit als dit is ingesteld op auto. Slimme vent.

Dus waarom duurt het zo lang? Wij keken mee 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
[...]

Wauw: 10 oproepen lstat(), 10 oproepen getxattr() (die allemaal mislukken omdat onze omgeving niet de attributen heeft waarnaar ls op zoek is), 10 oproepen capget().

Dit kan zeker geoptimaliseerd worden.

Mogelijkheden attribuut? Nee

Advies opvolgen bug van 10 jaar geleden, hebben we geprobeerd de attribuutcontrole uit te schakelen mogelijkheden:

$ 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

Wauw, tot 8 seconden acceleratie! We zijn van al die dure telefoontjes af getxattr()en uitdagingen capget() ook verdwenen, geweldig.

Maar er zijn nog steeds die vervelende telefoontjes lstat(), Hoewel…

Hoeveel bloemen heb je nodig?

Daarom gingen we het eens nader bekijken LS_COLORS.

Eerst hebben we eenvoudigweg deze variabele uitgeschakeld:

$ 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

Wat!?! Nog 13 seconden?

Het blijkt dat wanneer de omgevingsvariabele LS_COLORS slechts één van de elementen is niet gedefinieerd of ontbreekt <type>=color:, het gebruikt standaard de ingebouwde database en gebruikt nog steeds kleuren. Dus als u de inkleuring voor een bepaald bestandstype wilt uitschakelen, moet u dit overschrijven met <type>=: of <type> 00 in bestand DIR_COLORS.

Na veel vallen en opstaan ​​hebben we onze zoektocht tot dit beperkt:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

die is geschreven als

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

Dit betekent: kleur bestanden niet op attribuut. mogelijkheden, maar beetje bij beetje setuid/setgid, ook niet door uitvoerbaarheid vlag.

Wij versnellen ls

En als u geen van deze controles uitvoert, belt u lstat() verdwijnen, en nu is het een heel andere zaak:

$ 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 seconden op een lijst van 10 bestanden, een record.

Sherlock opzetten

Van 13 seconden met standaardinstellingen tot 0,3 seconden met kleine aanpassingen LS_COLORS betekent een 40-voudige versnelling door afwezigheid setuid / setgid en gekleurde uitvoerbare bestanden. Niet zo'n groot verlies.

Uiteraard wordt dit nu voor elke gebruiker in Sherlock geconfigureerd.

Maar als u de kleuring wilt retourneren, kunt u eenvoudig terugkeren naar de standaardinstellingen:

$ unset LS_COLORS

Maar zorg ervoor dat u in mappen met veel bestanden koffie zet terwijl deze actief is ls.

Bron: www.habr.com

Voeg een reactie