Kada varijabla okoline ubrza proces 40 puta

Danas želimo razgovarati o nekim od najnovijih ažuriranja sustava Sherlock [ovo je klaster visokih performansi na Sveučilištu Stanford - cca. trans.], koji znatno ubrzavaju ispisivanje datoteka u direktorije s velikim brojem unosa.

Za razliku od uobičajenih članaka, ovo je više insajdersko izvješće o tome kako redovito radimo na Sherlocku kako bismo ga održali u najboljem redu za naše korisnike. Nadamo se da ćemo objaviti više ovakvih članaka u budućnosti.

Ispisivanje velikog broja datoteka zahtijeva vrijeme

Sve je počelo s pitanjem tehničke podrške jednog korisnika. On je izvijestio o problemu da ovrha ls traje nekoliko minuta u imeniku s više od 15 000 unosa $SCRATCH [direktorij za privremene datoteke - cca. traka].

Tisuće datoteka u jednom direktoriju obično predstavljaju teret za datotečni sustav i to se nikako ne preporučuje. Korisnik je to znao i priznao je da to nije dobro, ali je spomenuo da je listanje bilo 1000 puta brže na njegovom laptopu od Sherlocka. Naravno, ovo nas je povrijedilo. Pa smo pogledali dublje.

Jer lijepo izgleda

Pogledali smo što zapravo radi ls prilikom ispisivanja imenika i zašto taj proces traje toliko dugo. Na većini modernih distribucija ls prema zadanim postavkama radi kao ls --color=auto, jer svi vole boje.

Ali lijepe boje imaju svoju cijenu: za svaku datoteku ls mora dobiti informacije o vrsti datoteke, njezinim dopuštenjima, zastavicama, proširenim atributima i slično kako bi odabrao odgovarajuću boju.

Jedno jednostavno rješenje problema je da se potpuno onemogući boja u ls-u, ali zamislite bijes korisnika. Ni pod kojim okolnostima ne smijete oduzeti ispis u boji, mi nismo čudovišta.

Pa smo gledali dublje. ls boje unose preko varijable okruženja LS_COLORS, koji je postavljen dircolors(1) na temelju konfiguracijske datoteke dir_colors(5)... Da, izvršna datoteka čita konfiguracijsku datoteku za stvaranje varijable okruženja, koja zatim koristi (i ako ne znate o datotekama vrata (do), zatim dir_colors će raditi, Unatoč svemu).

Pogledajmo pobliže

Kako bismo odredili koja shema boja uzrokuje usporavanje, stvorili smo eksperimentalno okruženje:

$ 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 sekundi za 10 000 datoteka, nije baš dobro.

Usput, treba nam zastava --color=always: iako se okreće prema ls --color=autoAli ls otkriva kada nije spojen na terminal (npr. cijevi ili s preusmjeravanjem izlaza) i onemogućuje bojanje ako je postavljeno na auto. Pametan tip.

Pa što traje toliko dugo? Pogledali smo sa 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
[...]

Vau: 10 000 poziva lstat(), 10 poziva getxattr() (koji svi ne uspijevaju jer naše okruženje nema atribute koje ls traži), 10 000 poziva capget().

To se sigurno može optimizirati.

Atribut sposobnosti? Ne

Slijedeći savjet bug od prije 10 godina, pokušali smo onemogućiti provjeru atributa sposobnosti:

$ 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

Wow, do 8 sekundi ubrzanja! Riješili smo se svih tih skupih poziva getxattr(), i izazove capget() nestala također, super.

Ali i dalje ima dosadnih poziva lstat(), iako…

Koliko cvijeća trebate?

Stoga smo malo bolje pogledali LS_COLORS.

Prvo smo jednostavno onemogućili ovu varijablu:

$ 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

Što!?! Još 13 sekundi?

Ispada da kada varijabla okoline LS_COLORS samo jedan njegov element nije definiran ili nedostaje <type>=color:, prema zadanim postavkama koristi ugrađenu bazu podataka i još uvijek koristi boje. Dakle, ako želite onemogućiti kolorizaciju za određenu vrstu datoteke, morate je nadjačati s <type>=: ili <type> 00 u spisu DIR_COLORS.

Nakon mnogo pokušaja i pogrešaka, suzili smo pretragu na ovo:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

koji je napisan kao

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

To znači: nemojte bojati datoteke prema atributima. sposobnostiali malo po malo setuid/setgid, niti po oznaka izvršnosti.

Ubrzavamo ls

A ako ne učinite nijednu od ovih provjera, onda pozivi lstat() nestati, a sada je sasvim druga stvar:

$ 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 sekunde na popisu od 10 000 datoteka, rekord.

Postavljanje Sherlocka

Od 13 sekundi sa zadanim postavkama do 0,3 sekunde s manjim prilagodbama LS_COLORS znači 40-struko ubrzanje zbog odsutnosti setuid / setgid i obojene izvršne datoteke. Nije tako veliki gubitak.

Naravno, ovo je sada konfigurirano u Sherlocku za svakog korisnika.

Ali ako želite vratiti bojenje, možete se jednostavno vratiti na zadane postavke:

$ unset LS_COLORS

Ali onda u direktorijima s puno datoteka, svakako skuhajte kavu dok radi ls.

Izvor: www.habr.com

Dodajte komentar