Danes želimo govoriti o nekaterih najnovejših posodobitvah sistema Sherlock [to je visoko zmogljiva gruča na Univerzi Stanford - pribl. prev.], ki bistveno pohitri izpisovanje datotek v imenike z velikim številom vnosov.
V nasprotju z običajnimi članki je to bolj kot notranje poročilo o tem, kako redno delamo na Sherlocku, da bi zagotovil najboljše delovanje za naše uporabnike. Upamo, da bomo v prihodnosti objavili več takšnih člankov.
Seznam številnih datotek zahteva čas
Vse se je začelo z vprašanjem tehnične podpore uporabnika. Je poročal o težavi, ki jo je izvedba ls
traja nekaj minut v imeniku z več kot 15 vnosi $SCRATCH
[imenik za začasne datoteke - pribl. vozni pas].
Na tisoče datotek v enem imeniku običajno predstavlja breme za datotečni sistem in vsekakor ni priporočljivo. Uporabnik je to vedel in priznal, da ni dobro, vendar je omenil, da je bil seznam na njegovem prenosniku 1000-krat hitrejši kot Sherlock. Seveda nas je to prizadelo. Zato smo pogledali globlje.
Ker izgleda lepo
Pogledali smo, kaj dejansko počne ls
pri navajanju imenika in zakaj postopek traja tako dolgo. Na večini sodobnih distribucij ls
privzeto teče kot ls --color=auto
, saj so barve všeč vsem.
Toda lepe barve imajo svojo ceno: za vsako datoteko ls
mora pridobiti podatke o vrsti datoteke, njenih dovoljenjih, zastavicah, razširjenih atributih in podobno, da izbere ustrezno barvo.
Ena preprosta rešitev problema je, da v celoti onemogočite barvo v ls, a predstavljajte si ogorčenje uporabnikov. V nobenem primeru ne smete odvzeti barvnega izpisa, nismo pošasti.
Zato smo pogledali globlje. ls
barvne vnose prek spremenljivke okolja LS_COLORS
, ki je nastavljen dircolors(1)
na podlagi konfiguracijske datoteke dir_colors(5)
. da
Pa poglejmo pobliže
Da bi ugotovili, katera barvna shema povzroča upočasnitev, smo ustvarili poskusno okolje:
$ 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 sekunde za 10 datotek, ni zelo dobro.
Mimogrede, potrebujemo zastavo
--color=always
: čeprav se obrača nals --color=auto
Vendarls
zazna, ko ni povezan s terminalom (npr. po cevi ali s preusmeritvijo izhoda) in onemogoči barvanje, če je nastavljenoauto
. Pameten tip.
Kaj torej traja tako dolgo? Pogledali smo 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
[...]
Vau: 10 klicev lstat()
, 10 klicev getxattr()
(ki vsi ne uspejo, ker naše okolje nima atributov, ki jih išče ls), 10 klicev capget()
.
Vsekakor se da to optimizirati.
Atribut zmogljivosti? ne
Po nasvetu
$ 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
Vau, do 8 sekund pospeška! Znebili smo se vseh tistih dragih klicev getxattr()
, in izzivi capget()
tudi izginilo, super.
Še vedno pa so ti nadležni klici lstat()
, Čeprav…
Koliko rožic potrebuješ?
Zato smo vzeli pobližje LS_COLORS
.
Najprej smo preprosto onemogočili to spremenljivko:
$ 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
Kaj!?! Še 13 sekund?
Izkazalo se je, da ko spremenljivka okolja LS_COLORS
samo eden od njegovih elementov ni opredeljen ali manjka <type>=color:
, privzeto uporablja vgrajeno bazo podatkov in še vedno uporablja barve. Torej, če želite onemogočiti barvanje za določeno vrsto datoteke, jo morate preglasiti z <type>=:
ali <type> 00
v datoteki DIR_COLORS
.
Po številnih poskusih in napakah smo naše iskanje zožili na tole:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
ki je zapisan kot
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
To pomeni: ne barvajte datotek po atributih.
, niti z
Pospešimo ls
In če ne opravite nobenega od teh pregledov, potem klici lstat()
izginejo, zdaj pa je povsem 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 seznamu 10 datotek, rekord.
Postavitev Sherlocka
Od 13 sekund s privzetimi nastavitvami do 0,3 sekunde z manjšimi prilagoditvami LS_COLORS
pomeni 40-kratni pospešek zaradi odsotnosti setuid
/ setgid
in barvne izvršljive datoteke. Ni tako velika izguba.
Seveda je to zdaj konfigurirano v Sherlocku za vsakega uporabnika.
Če pa želite vrniti barvo, se lahko preprosto vrnete na privzete nastavitve:
$ unset LS_COLORS
Toda v imenikih z veliko datotekami ne pozabite skuhati kave, medtem ko teče ls
.
Vir: www.habr.com