Keď premenná prostredia zrýchli proces 40-krát

Dnes chceme hovoriť o niektorých najnovších aktualizáciách systému Sherlock [toto je vysoko výkonný klaster na Stanfordskej univerzite - cca. trans.], ktoré výrazne urýchľujú výpis súborov v adresároch s veľkým počtom záznamov.

Na rozdiel od bežných článkov ide skôr o zasvätenú správu o tom, ako pravidelne pracujeme na Sherlockovi, aby pre našich používateľov fungoval čo najlepšie. Dúfame, že v budúcnosti uverejníme viac takýchto článkov.

Vypísanie mnohých súborov si vyžaduje čas

Všetko to začalo otázkou technickej podpory od používateľa. Nahlásil problém, že exekúcia ls trvá niekoľko minút v adresári s viac ako 15 000 záznamami $SCRATCH [adresár pre dočasné súbory - cca. pruh].

Tisíce súborov v jednom adresári zvyčajne predstavujú záťaž pre súborový systém a rozhodne sa neodporúčajú. Používateľ to vedel a priznal, že to nie je dobré, ale spomenul, že výpis bol na jeho notebooku 1000-krát rýchlejší ako Sherlock. Samozrejme, že nás to bolelo. Tak sme sa pozreli hlbšie.

Pretože vyzerá pekne

Pozreli sme sa na to, čo to vlastne robí ls pri vypisovaní adresára a prečo tento proces trvá tak dlho. Na väčšine moderných distribúcií ls štandardne beží ako ls --color=auto, pretože farby má každý rád.

Ale krásne farby majú svoju cenu: za každý súbor ls musí získať informácie o type súboru, jeho oprávneniach, príznakoch, rozšírených atribútoch a podobne, aby si vybral vhodnú farbu.

Jedným jednoduchým riešením problému je úplne zakázať farbu v ls, ale predstavte si pobúrenie používateľov. V žiadnom prípade by ste nemali odoberať farebný výstup, nie sme žiadne monštrá.

Tak sme sa pozreli hlbšie. ls zadanie farieb cez premennú prostredia LS_COLORS, ktorý je nastavený dircolors(1) na základe konfiguračného súboru dir_colors(5). Áno, spustiteľný súbor načíta konfiguračný súbor, aby vytvoril premennú prostredia, ktorú potom použije (a ak neviete o súboroch dvere (do), potom dir_colors bude pracovať, Napriek všetkému).

Poďme sa na to pozrieť bližšie

Aby sme určili, ktorá farebná schéma spôsobuje spomalenie, vytvorili sme experimentálne prostredie:

$ 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 sekundy pre 10 000 súborov, nie veľmi dobré.

Mimochodom, potrebujeme vlajku --color=always: hoci sa obracia k ls --color=autoAle ls detekuje, keď nie je pripojený k terminálu (napr. potrubím alebo s presmerovaním výstupu) a deaktivuje farbenie, ak je nastavené na auto. Šikovný chlap.

Tak čo to tak dlho trvá? Pozreli sme sa s 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
[...]

Páni: 10 000 hovorov lstat(), 10 000 hovorov getxattr() (ktoré všetky zlyhajú, pretože naše prostredie nemá atribúty, ktoré ls hľadá), 10 000 hovorov capget().

Určite sa to dá optimalizovať.

Atribút schopností? nie

Nasledovanie rady chyba spred 10 rokov, pokúsili sme sa vypnúť kontrolu atribútov možnosti:

$ 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

Páni, zrýchlenie až 8 sekúnd! Zbavili sme sa všetkých tých drahých hovorov getxattr()a výzvy capget() zmizol tiež, super.

Ale stále existujú tieto nepríjemné hovory lstat(), Hoci…

Koľko kvetov potrebujete?

Preto sme sa na to pozreli bližšie LS_COLORS.

Najprv sme jednoducho zakázali túto premennú:

$ 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

Čo!?! Ešte 13 sekúnd?

Ukazuje sa, že keď je prostredie premenné LS_COLORS len jeden z jeho prvkov nie je definovaný alebo chýba <type>=color:, štandardne používa vstavanú databázu a stále používa farby. Ak teda chcete zakázať sfarbenie pre určitý typ súboru, musíte ho prepísať <type>=: alebo <type> 00 v súbore DIR_COLORS.

Po mnohých pokusoch a omyloch sme naše vyhľadávanie zúžili na toto:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

ktorý sa píše ako

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

To znamená: nefarbiť súbory podľa atribútu. možnosti, ale kúsok po kúsku setuid/setgid, ani tým príznak vykonateľnosti.

Zrýchlime ls

A ak neurobíte žiadnu z týchto kontrol, zavolajte lstat() zmizne a teraz je to úplne iná vec:

$ 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 sekundy na zozname 10 000 súborov, rekord.

Nastavenie Sherlocka

Od 13 sekúnd s predvolenými nastaveniami po 0,3 sekundy s malými úpravami LS_COLORS znamená 40-násobné zrýchlenie v dôsledku absencie setuid / setgid a farebné spustiteľné súbory. Nie až taká veľká strata.

Samozrejme, toto je teraz nakonfigurované v Sherlocku pre každého používateľa.

Ak však chcete vrátiť sfarbenie, môžete sa jednoducho vrátiť k predvoleným nastaveniam:

$ unset LS_COLORS

Ale potom v adresároch s množstvom súborov nezabudnite variť kávu za chodu ls.

Zdroj: hab.com

Pridať komentár