Wanneer 'n omgewingsveranderlike die proses met 40 keer versnel

Vandag wil ons praat oor sommige van die nuutste opdaterings aan die Sherlock-stelsel [dit is 'n hoëprestasie-kluster by Stanford Universiteit - ongeveer. trans.], wat die lys van lêers in gidse met 'n groot aantal inskrywings aansienlik versnel.

Anders as gewone artikels, is dit meer 'n insider-verslag oor hoe ons gereeld aan Sherlock werk om dit op sy beste vir ons gebruikers aan die gang te hou. Ons hoop om meer artikels soos hierdie in die toekoms te publiseer.

Om baie lêers te lys neem tyd

Dit het alles begin met 'n tegniese ondersteuningsvraag van 'n gebruiker. Hy het 'n probleem gerapporteer dat die teregstelling ls neem 'n paar minute in 'n gids met meer as 15 000 inskrywings in $SCRATCH [gids vir tydelike lêers - ongeveer. baan].

Duisende lêers in een gids hou gewoonlik 'n las vir die lêerstelsel in en word beslis nie aanbeveel nie. Die gebruiker het dit geweet en erken dat dit nie goed was nie, maar het genoem dat die notering 1000 keer vinniger op sy skootrekenaar was as Sherlock. Dit het ons natuurlik seergemaak. So ons het dieper gekyk.

Want dit lyk mooi

Ons het gekyk na wat dit eintlik doen ls wanneer 'n gids gelys word, en waarom die proses so lank neem. Op die meeste moderne verspreidings ls by verstek loop dit as ls --color=auto, want almal hou van die kleure.

Maar pragtige kleure het 'n prys: vir elke lêer ls moet inligting oor die lêertipe, sy toestemmings, vlae, uitgebreide eienskappe en dies meer bekom om die toepaslike kleur te kies.

Een eenvoudige oplossing vir die probleem is om kleur in ls heeltemal uit te skakel, maar stel jou die verontwaardiging van gebruikers voor. Moet onder geen omstandighede die kleuruitset wegneem nie, ons is nie monsters nie.

So ons het dieper gekyk. ls kleur inskrywings via omgewingsveranderlike LS_COLORS, wat ingestel is dircolors(1) gebaseer op konfigurasielêer dir_colors(5)... Ja, die uitvoerbare lees die konfigurasielêer om 'n omgewingsveranderlike te skep, wat dan gebruik word (en as jy nie van lêers weet nie deur (doen), dan dir_colors Sal werk, Ten spyte van alles).

Kom ons kyk van naderby

Om te bepaal watter kleurskema die verlangsaming veroorsaak, het ons 'n eksperimentele omgewing geskep:

$ 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 sekondes vir 10 000 lêers, nie baie goed nie.

Terloops, ons het 'n vlag nodig --color=always: hoewel hy na ls --color=autoMaar ls bespeur wanneer dit nie aan 'n terminaal gekoppel is nie (bv. deur pyp of met uitsetherleiding) en deaktiveer kleur as dit gestel is op auto. Slim ou.

So wat vat so lank? Ons het saam gekyk 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
[...]

Sjoe: 10 000 oproepe lstat(), 10 000 oproepe getxattr() (wat alles misluk omdat ons omgewing nie die eienskappe het waarna ons soek nie), 10 000 oproepe capget().

Dit kan sekerlik geoptimaliseer word.

Eienskap van vermoëns? Nope

Na aanleiding van advies gogga van 10 jaar gelede, het ons probeer om kenmerkkontrole te deaktiveer vermoëns:

$ 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

Sjoe, tot 8 sekondes se versnelling! Ons het ontslae geraak van al daardie duur oproepe getxattr(), en uitdagings capget() het ook verdwyn, wonderlik.

Maar daar is nog steeds hierdie irriterende oproepe lstat(), Alhoewel...

Hoeveel blomme het jy nodig?

Daarom het ons dit van naderby bekyk LS_COLORS.

Eerstens het ons eenvoudig hierdie veranderlike gedeaktiveer:

$ 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 sekondes?

Dit blyk dat wanneer die omgewing veranderlike LS_COLORS slegs een van sy elemente is nie gedefinieer nie of ontbreek <type>=color:, dit gebruik die ingeboude databasis by verstek en gebruik steeds kleure. As jy dus inkleuring vir 'n sekere lêertipe wil deaktiveer, moet jy dit ignoreer <type>=: of <type> 00 in lêer DIR_COLORS.

Na baie beproewing en fout, het ons ons soektog tot hierdie beperk:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

wat geskryf is as

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

Dit beteken: moenie lêers volgens kenmerk kleur nie. vermoëns, maar bietjie vir bietjie setuid/setgid, ook nie deur nie uitvoerbaarheid vlag.

Ons versnel ls

En as jy nie enige van hierdie tjeks doen nie, bel dan lstat() verdwyn, en nou is dit 'n heeltemal ander saak:

$ 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 sekondes op 'n lys van 10 000 lêers, 'n rekord.

Stel Sherlock op

Van 13 sekondes met verstekinstellings tot 0,3 sekondes met geringe aanpassings LS_COLORS beteken 'n 40-voudige versnelling as gevolg van die afwesigheid setuid / setgid en gekleurde uitvoerbare lêers. Nie so 'n groot verlies nie.

Natuurlik is dit nou vir elke gebruiker in Sherlock opgestel.

Maar as jy die kleur wil teruggee, kan jy eenvoudig terugkeer na die verstekinstellings:

$ unset LS_COLORS

Maar dan op gidse met baie lêers, maak seker dat jy koffie brou terwyl dit aan die gang is ls.

Bron: will.com

Voeg 'n opmerking