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,
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 premals --color=auto
Alils
otkriva kada nije spojen na terminal (npr. cijevi ili s preusmjeravanjem izlaza) i onemogućuje bojanje ako je postavljeno naauto
. 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
$ 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.
, niti po
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