Når en miljøvariabel fremskynder processen 40 gange

I dag vil vi tale om nogle af de nyeste opdateringer af Sherlock-systemet [det er en højtydende klynge fra Stanford Universitet - oversættelsesnote], som betydeligt accelererer opstillingen af filer i kataloger med mange poster.

I modsætning til almindelige artikler er dette snarere en insiderrapport om, hvordan det regelmæssige arbejde med Sherlock foregår for at holde det i bedst mulig stand for vores brugere. Vi håber at publicere flere sådanne artikler i fremtiden.

Opstillingen af mange filer tager tid.

Det hele begyndte med et spørgsmål til supporten fra en bruger. Han rapporterede om et problem, at udførelsen ls tager flere minutter i et katalog med over 15.000 poster i $SCRATCH [et katalog til midlertidige filer - oversættelsesnote].

Tusinder af filer i ét katalog skaber normalt problemer for filsystemet, og det er bestemt ikke anbefalet. Brugeren vidste dette og erkendte, at det ikke var godt, men nævnte, at på hans bærbare computer gik opstillingen 1000 gange hurtigere end i Sherlock. Selvfølgelig ramte det os. Derfor kiggede vi dybere.

Fordi ls ser godt ud.

Vi undersøgte, hvad der faktisk sker ls ved opstilling af et katalog, og hvorfor processen tager så lang tid. I de fleste moderne distributioner ls udføres som standard ls --color=auto, fordi alle kan lide farver.

Men de smukke farver har en pris: for hver fil ls skal information om filtypen, dens tilladelser, flag, udvidede attributter og lignende hentes for at vælge den rigtige farve.

En af de enkle løsninger på problemet er at deaktivere farver i ls helt, men forestil dig brugernes oprør. Man kan på ingen måde fjerne den farvede output; vi er ikke monstre.

Derfor kiggede vi dybere. ls farvelægger posterne gennem miljøvariablen LS_COLORS, som er defineret af dircolors(1) baseret på konfigurationsfilen dir_colors(5).Ja, den eksekverbare fil læser konfigurationsfilen for at skabe miljøvariablen, som senere bruges af ls (og hvis du ikke kender til filer door (do), så fungerer dir_colors , uanset hvad.Lad os undersøge det nærmere.

For at bestemme, hvilken af farveskemaerne der forårsager langsomheden, skabte vi et eksperimentelt miljø:

Чтобы определить, какая из схем расцвечивания вызывает замедление, мы создали экспериментальную среду:

$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # forsøg ikke dette derhjemme!
$ time ls --color=always $SCRATCH/dont | wc -l
10000

real    0m12.758s
user    0m0.104s
sys     0m0.699s

12,7 sekunder for 10.000 filer, ikke så godt.

For resten, har vi brug for en flag --color=always: selvom den ændrer sig til ls --color=auto, men ls den opdager, når den ikke er tilsluttet terminalen (f.eks. via en kanal eller med omdirigering af output) og deaktiverer farvningen, hvis det er angivet auto. Smart fyr.

Hvad tager så lang tid? Vi så på det med strace:

$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% tid     sekunder  mikrosekunder/prædiko     kald     fejl 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
[...]

Hold da op: 10.000 kald lstat(), 10.000 kald getxattr() (som alle fejler, fordi der ikke er nogen attributter i vores miljø, som ls søger efter), 10.000 kald capget().

Det må kunne optimeres.

Capabilities-attribut? Nej.

Ifølge anbefalingerne en 10-år gammel bug, forsøgte vi at deaktivere attributkontrollen capabilities:

$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% tid     sekunder  mikrosekunder/prædiko     kald     fejl 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, accelerationen til 8 sekunder! Vi har fjernet alle disse dyre kald getxattr(), og kald capget() er også forsvundet, fantastisk.

Men der er stadig disse irriterende kald lstat(), selvom …

Hvor mange farver er nødvendige?

Så vi kiggede nærmere på LS_COLORS.

Først slukkede vi bare denne variabel:

$ 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

Hvad!?! Er det stadig 13 sekunder?

Det viser sig, at når miljøvariablen LS_COLORS hverken er defineret eller kun én af dens elementer mangler =color:, bruger den som standard den indbyggede farvedatabase og anvender stadig farver. Så hvis du vil deaktivere fremhævelsen for en bestemt filtype, skal du overstyre den med = eller 00 i filen DIR_COLORS.

Efter mange forsøg og fejl indsnævrede vi søgningen til dette:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

som skrives som

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

Det betyder: fremhæv ikke filer hverken efter attributter capabilities, eller efter bits setuid/setgid, eller efter eksekveringsflaget.

Vi øger hastigheden ls

Og hvis ingen af disse kontrolpunkter udføres, forsvinder kald og nu er det en helt anden sag: lstat() $ export LS_COLORS='ex=00:su=00:sg=00:ca=00:' $ time strace -c ls --color=always $SCRATCH/dont | wc -l 10000 % tid sekunder brugt pr. kald kald fejl 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 i altreal 0m0.337s user 0m0.032s sys 0m0.029s

0,3 sekunder for en liste med 10.000 filer, rekord.

Tilpasser Sherlock

Fra 13 sekunder med standardindstillinger til 0,3 sekunder med en lille justering

betyder 40 gange hurtigere takket være fraværet af LS_COLORS og fremhævede eksekverbare filer. Ikke så stort et tab. setuid / setgid и раскрашенных исполняемых файлов. Не такая большая потеря.

Selvfølgelig, nu er dette indstillet i Sherlock for hver bruger.

Men hvis du vil have farveskemaet tilbage, kan du blot vende tilbage til standardindstillingerne:

$ unset LS_COLORS

Men så skal du helt klart brygge kaffe, mens det kører på kataloger med mange filer. ls.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster