Keď environmentálna premenná urýchli proces 40-násobne

Dnes chceme hovoriti o niektorých posledných aktualizáciách systému Sherlock [je to vysoko výkonný klaster Stanfordovej univerzity — pozn. prekl.], ktoré výrazne zrýchľujú zoznamovanie súborov v adresároch s veľkým počtom záznamov.

Na rozdiel od bežných článkov, toto je skôr insider správa o tom, ako prebieha pravidelná práca na Sherlocku, aby sme ho udržali v najlepšom stave pre našich používateľov. Dúfame, že v budúcnosti budeme publikovať viac takýchto článkov.

Zoznam mnohých súborov trvá čas

Všetko sa začalo z otázky na technickú podporu od používateľa. Informoval o probléme, že vykonanie ls trvá niekoľko minút v adresári s viac ako 15 000 záznamami v $SCRATCH [adresár pre dočasné súbory — pozn. prekl.].

Tisíce súborov v jednom adresári zvyčajne spôsobujú ťažkosti pre súborový systém, a to sa určite neodporúča. Používateľ to vedel a uznal, že to nie je dobré, ale spomenul, že na jeho notebooku sa zoznamovanie vykonáva 1000-krát rýchlejšie než v Sherlocku. Samozrejme, to nás zasiahlo. Preto sme sa pozreli hlbšie.

Pretože ls vyzerá pekne

Skontrolovali sme, čo vlastne robí ls pri zoznamovaní adresára a prečo tento proces trvá tak dlho. Vo väčšine moderných distribúcií ls sa predvolene vykonáva ako ls --color=auto, pretože všetkým sa páči farba.

Ale pekné farby majú svoju cenu: pre každý súbor ls musí získať informácie o type súboru, jeho právach, vlajkách, rozšírených atribútoch a podobne, aby mohol zvoliť príslušnú farbu.

Jedno z jednoduchých riešení problému — úplne vypnúť farbu v ls, ale predstavte si pobúrenie používateľov. V žiadnom prípade sa nemôžeme vzdať farebného výstupu, nie sme monštrá.

Preto sme sa pozreli hlbšie. ls farbí záznamy prostredníctvom premennej prostredia LS_COLORS, ktorú nastavuje dircolors(1) na základe konfiguračného súboru dir_colors(5). Áno, spustiteľný súbor číta konfiguračný súbor na vytvorenie premennej prostredia, ktorú potom používa ls (a ak neviete o súboroch door (do), tak dir_colors bude fungovať, bez ohľadu na to, čo.)

Pozrime sa podrobnejšie

Aby sme určili, ktorá zo schém zafarbenia spôsobuje spomalenie, vytvorili sme experimentálne prostredie:

$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # nerobte to doma!
$ time ls --color=always $SCRATCH/dont | wc -l
10000

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

12,7 sekundy na 10 000 súborov, nie veľmi dobre.

Mimochodom, potrebujeme flag --color=always: hoci sa zmení na ls --color=auto, ale ls zistí, keď nie je pripojený k terminálu (napr. cez kanál alebo s presmerovaním výstupu) a vypne farbenie, ak je nastavená hodnota auto. Chytrý chlapec.

Tak čo zaberá toľko času? Pozreli sme sa pomocou 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
[...]

No pekne: 10 000 volaní lstat(), 10 000 volaní getxattr() (ktoré všetky zlyhávajú, pretože v našom prostredí nie sú atribúty, ktoré hľadá ls), 10 000 volaní capget().

Určite to môžeme optimalizovať.

Atribút capabilities? Nie.

Podľa rád chyby z pred 10 rokmi, pokúsili sme sa vypnúť overovanie atribútu capabilities:

$ 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 celkom

real    0m8.160s
user    0m0.115s
sys     0m0.961s

Wow, urýchlenie na 8 sekúnd! Zbavili sme sa všetkých tých drahých volaní getxattr(), a volania capget() tiež zmizli, výborne.

Ale ešte ostali tieto otravné volania lstat(), hoci...

Koľko farieb potrebujeme?

Preto sme sa pozreli na LS_COLORS.

Najprv sme jednoducho vypnuli 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 stále 13 sekúnd?

Ukazuje sa, že keď je premenná prostredia LS_COLORS neurčená alebo chýba iba jeden z jej prvkov =color:, predvolene používa zabudovanú databázu a aj tak používa farby. Preto, ak chcete vypnúť farebné zvýraznenie pre konkrétny typ súboru, musíte ju predefinovať s pomocou =: alebo 00 v súbore DIR_COLORS.

Po mnohých pokusoch a omyloch sme zúžili hľadanie na toto:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

čo sa zapisuje ako

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

To znamená: nefarbiť súbory podľa atribútu capabilities, ale podľa bitov setuid/setgid, ani podľa práva na vykonávanie.

Zrýchlenie ls

A ak sa neučíme žiadnu z týchto kontrol, potom volania lstat() zmiznú, 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.

Nastavujeme Sherlock

Od 13 sekúnd s predvolenými nastaveniami po 0,3 sekundy s drobným nastavením LS_COLORS znamená 40-násobné zrýchlenie absenciou setuid / setgid a farebných vykonávacích súborov. Nie tak veľká strata.

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

Ale ak chcete obnoviť farbenie, môžete sa jednoducho vrátiť k predvoleným nastaveniam:

$ unset LS_COLORS

Ale potom si na adresároch s veľkým množstvom súborov určite uvarte kávu, kým to funguje. ls.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster