Kai aplinkos kintamasis pagreitina procesą 40 kartų

Šiandien norime pakalbėti apie kai kuriuos naujausius Sherlock sistemos atnaujinimus [tai didelio našumo klasteris Stanfordo universitete – apytiksliai. trans.], kurios žymiai pagreitina failų įtraukimą į katalogus, kuriuose yra daug įrašų.

Skirtingai nuo įprastų straipsnių, tai labiau viešai neatskleista informacija apie tai, kaip mes reguliariai dirbame su Sherlock, kad jis veiktų kuo geriau mūsų vartotojams. Tikimės ateityje paskelbti daugiau tokių straipsnių.

Daugelio failų sąrašas užtrunka

Viskas prasidėjo nuo vartotojo techninės pagalbos klausimo. Jis pranešė apie egzekucijos problemą ls užtrunka kelias minutes kataloge, kuriame yra daugiau nei 15 000 įrašų $SCRATCH [laikinųjų failų katalogas – apytiksl. juosta].

Tūkstančiai failų viename kataloge paprastai yra našta failų sistemai ir tikrai nerekomenduojama. Vartotojas tai žinojo ir pripažino, kad tai nėra gerai, tačiau paminėjo, kad jo nešiojamajame kompiuteryje įrašas buvo 1000 kartų greitesnis nei „Sherlock“. Žinoma, tai mus įskaudino. Taigi žiūrėjome giliau.

Nes gražiai atrodo

Pažiūrėjome, ką jis iš tikrųjų daro ls įtraukiant katalogą ir kodėl procesas užtrunka taip ilgai. Daugumoje šiuolaikinių paskirstymų ls pagal numatytuosius nustatymus jis veikia kaip ls --color=auto, nes spalvos patinka visiems.

Tačiau gražios spalvos turi savo kainą: už kiekvieną failą ls turi gauti informaciją apie failo tipą, jo teises, vėliavėles, išplėstinius atributus ir panašiai, kad galėtų pasirinkti tinkamą spalvą.

Vienas paprastas problemos sprendimas yra visiškai išjungti spalvą ls, tačiau įsivaizduokite vartotojų pasipiktinimą. Jokiu būdu neturėtumėte atimti spalvų išvesties, mes nesame monstrai.

Taigi žiūrėjome giliau. ls spalvų įrašai per aplinkos kintamąjį LS_COLORS, kuris nustatytas dircolors(1) remiantis konfigūracijos failu dir_colors(5)... taip, vykdomasis failas nuskaito konfigūracijos failą, kad sukurtų aplinkos kintamąjį, kurį ls tada naudoja (ir jei nežinote apie failus durys (do), tada dir_colors veiks, Nepaisant visko).

Pažiūrėkime atidžiau

Norėdami nustatyti, kuri spalvų schema sukelia sulėtėjimą, sukūrėme eksperimentinę aplinką:

$ 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 sekundės 10 000 failų, nelabai gerai.

Beje, mums reikia vėliavos --color=always: nors jis kreipiasi į ls --color=autoBet ls aptinka, kai jis nėra prijungtas prie terminalo (pvz., vamzdžiu arba su išvesties peradresavimu), ir išjungia spalvinimą, jei nustatyta auto. Protingas vaikinas.

Taigi, kas taip ilgai trunka? Mes žiūrėjome su 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
[...]

Oho: 10 000 skambučių lstat(), 10 000 skambučių getxattr() (viskas nepavyksta, nes mūsų aplinka neturi atributų, kurių ieško ls), 10 000 skambučių capget().

Žinoma, tai gali būti optimizuota.

Galimybių atributas? Ne

Vadovaudamiesi patarimu klaida prieš 10 metų, bandėme išjungti atributų tikrinimą galimybes:

$ 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

Oho, iki 8 sekundžių pagreitis! Atsikratėme visų tų brangių skambučių getxattr(), ir iššūkiai capget() irgi dingo, puiku.

Tačiau vis tiek yra tokių erzinančių skambučių lstat(), nors…

Kiek gėlių jums reikia?

Todėl pasižiūrėjome atidžiau LS_COLORS.

Pirmiausia tiesiog išjungėme šį kintamąjį:

$ 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

Ką!?! Dar 13 sekundžių?

Pasirodo, kad kai aplinkos kintamasis LS_COLORS tik vienas jo elementas neapibrėžtas arba jo trūksta <type>=color:, pagal numatytuosius nustatymus ji naudoja integruotą duomenų bazę ir vis tiek naudoja spalvas. Taigi, jei norite išjungti spalvinimą tam tikram failo tipui, turite jį nepaisyti <type>=: arba <type> 00 faile DIR_COLORS.

Po daugybės bandymų ir klaidų susiaurinome paiešką iki šios:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

kuri parašyta kaip

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

Tai reiškia: nespalvinkite failų pagal atributą. galimybes, bet po truputį setuid/setgid, nei pagal Vykdomumo vėliavėlė.

Paspartiname ls

Ir jei neatliksite nė vieno iš šių patikrinimų, tada skambinkite lstat() dingsta, o dabar visai kitas reikalas:

$ 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 sekundės 10 000 failų sąraše – rekordas.

Sherlock nustatymas

Nuo 13 sekundžių su numatytaisiais nustatymais iki 0,3 sekundės su nedideliais pakeitimais LS_COLORS reiškia 40 kartų pagreitį dėl nebuvimo setuid / setgid ir spalvotus vykdomuosius failus. Ne toks didelis praradimas.

Žinoma, dabar tai sukonfigūruota „Sherlock“ kiekvienam vartotojui.

Bet jei norite grąžinti spalvą, galite tiesiog grįžti į numatytuosius nustatymus:

$ unset LS_COLORS

Bet tada kataloguose, kuriuose yra daug failų, būtinai virkite kavą, kol ji veikia ls.

Šaltinis: www.habr.com

Добавить комментарий