Když proměnná prostředí zrychlí proces 40krát

Dnes chceme mluvit o některých nejnovějších aktualizacích systému Sherlock [jedná se o vysoce výkonný cluster na Stanfordské univerzitě - cca. trans.], které výrazně zrychlují výpis souborů v adresářích s velkým počtem záznamů.

Na rozdíl od běžných článků se jedná spíše o zasvěcenou zprávu o tom, jak pravidelně pracujeme na Sherlockovi, aby pro naše uživatele fungoval co nejlépe. Doufáme, že v budoucnu budeme publikovat více podobných článků.

Výpis mnoha souborů vyžaduje čas

Všechno to začalo otázkou technické podpory od uživatele. Nahlásil problém, že exekuce ls trvá několik minut v adresáři s více než 15 000 záznamy $SCRATCH [adresář pro dočasné soubory - cca. pruh].

Tisíce souborů v jednom adresáři obvykle představují zátěž pro souborový systém a rozhodně se nedoporučují. Uživatel to věděl a připustil, že to není dobré, ale zmínil, že výpis byl na jeho notebooku 1000krát rychlejší než Sherlock. Samozřejmě nás to bolelo. Tak jsme se podívali hlouběji.

Protože vypadá hezky

Podívali jsme se, co to vlastně dělá ls při výpisu adresáře a proč tento proces trvá tak dlouho. Na většině moderních distribucí ls standardně běží jako ls --color=auto, protože každý má rád barvy.

Ale krásné barvy mají svou cenu: za každý pilník ls musí získat informace o typu souboru, jeho oprávněních, příznacích, rozšířených atributech a podobně, aby mohl vybrat vhodnou barvu.

Jedním jednoduchým řešením problému je úplně zakázat barvu v ls, ale představte si pobouření uživatelů. Za žádných okolností neodeberte barevný výstup, nejsme žádná monstra.

Tak jsme se podívali hlouběji. ls zadání barev pomocí proměnné prostředí LS_COLORS, který je nastaven dircolors(1) na základě konfiguračního souboru dir_colors(5)... Ano, spustitelný soubor načte konfigurační soubor, aby vytvořil proměnnou prostředí, kterou pak použije (a pokud nevíte o souborech dveře (do), pak dir_colors bude to fungovat, Navzdory všemu).

Pojďme se na to podívat blíže

Abychom zjistili, které barevné schéma způsobuje zpomalení, vytvořili jsme experimentální prostředí:

$ 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 pro 10 000 souborů, ne příliš dobré.

Mimochodem, potřebujeme vlajku --color=always: ačkoli se obrací k ls --color=autoavšak ls detekuje, když není připojen k terminálu (např. potrubím nebo s přesměrováním výstupu) a deaktivuje barvení, pokud je nastaveno na auto. Chytrý chlap.

Tak co to trvá tak dlouho? Dívali jsme se 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 hovorů lstat(), 10 000 hovorů getxattr() (které všechny selžou, protože naše prostředí nemá atributy, které ls hledá), 10 000 hovorů capget().

Určitě se to dá optimalizovat.

Atribut schopností? ani náhodou

Následovat rady chyba z doby před 10 lety, pokusili jsme se vypnout kontrolu atributů schopnosti:

$ 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, až 8 sekund zrychlení! Zbavili jsme se všech těch drahých hovorů getxattr()a výzvy capget() taky zmizel, super.

Ale stále existují tyto nepříjemné hovory lstat(), Ačkoli…

Kolik květin potřebujete?

Proto jsme se podívali blíže LS_COLORS.

Nejprve jsme jednoduše zakázali tuto proměnnou:

$ 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

Co!?! Ještě 13 sekund?

Ukazuje se, že když je proměnná prostředí LS_COLORS pouze jeden z jeho prvků není definován nebo chybí <type>=color:, ve výchozím nastavení používá vestavěnou databázi a stále používá barvy. Pokud tedy chcete zakázat barvení pro určitý typ souboru, musíte jej přepsat pomocí <type>=: nebo <type> 00 v souboru DIR_COLORS.

Po mnoha pokusech a omylech jsme naše hledání zúžili na toto:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

který se píše jako

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

To znamená: nebarvit soubory podle atributu. schopnosti, ale kousek po kousku setuid/setgid, ani tím příznak proveditelnosti.

Zrychlujeme ls

A pokud žádnou z těchto kontrol neprovedete, zavolejte lstat() zmizí a teď je to úplně jiná věc:

$ 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 seznamu 10 000 souborů, rekord.

Nastavení Sherlocka

Od 13 sekund s výchozím nastavením po 0,3 sekundy s drobnými úpravami LS_COLORS znamená 40násobné zrychlení v důsledku absence setuid / setgid a barevné spustitelné soubory. Ne tak velká ztráta.

To je samozřejmě nyní nakonfigurováno v Sherlocku pro každého uživatele.

Pokud však chcete vrátit zbarvení, můžete se jednoduše vrátit k výchozímu nastavení:

$ unset LS_COLORS

Ale pak v adresářích se spoustou souborů nezapomeňte vařit kávu za chodu ls.

Zdroj: www.habr.com

Přidat komentář