Kur variabla e mjedisit shp brenda 40 herë më shpejt procesin

Sot duam të flasim për disa përditësime të fundit të sistemit Sherlock [këtu është një klasë me performancë të lartë nga Universiteti i Stanfordit - shën. red.], të cilat ndihmojnë të përshpejtojnë listimin e skedarëve në katalogët me një numër të madh regjistrimesh.

Në ndryshim nga artikujt e zakonshëm, kjo është më shumë një raport brenda-vendit për atë se si realizohet punën e rregullt mbi Sherlock, për ta mbajtur atë në gjendjen më të mirë për përdoruesit tanë. Shpresojmë të publikojmë më shumë artikuj të tillë në të ardhmen.

Listimi i shumë skedarëve merr kohë

Ishte një fillim me një pyetje në mbështetje nga një përdorues. Ai raportoi një problem, ku ekzekutimi ls merr disa minuta në një katalog me më shumë se 15,000 regjistrime në $SCRATCH [katalogu për skedarët temporary - shën. red.].

Mijëra skedarë në një katalog zakonisht krijojnë vështirësi për sistemin e skedarëve dhe kjo definitivisht nuk rekomandohet. Përdoruesi e dinte këtë dhe e pranoi se nuk ishte mirë, por përmendi se në laptopin e tij listimi ekzekutohej 1000 herë më shpejt sesa në Sherlock. Sigurisht, kjo na lëndoi. Prandaj shikua më thellë.

Sepse ls duket bukur

Ne shqyrtuam se çfarë bënë realisht ls në listimin e katalogut, dhe pse procesi merr kaq shumë kohë. Në shumicën e distribucioneve moderne ls për default ekzekutohet si ls --color=auto, sepse të gjithëve u pëlqen ngjyra.

Por ngjyrat e bukura kanë një çmim: për çdo skedar ls duhet të marrë informacion mbi llojin e skedarit, lejet e tij, flamujt, atributet e zgjatura dhe kështu me radhë, për të zgjedhur ngjyrën përkatëse.

Një nga zgjidhjet e thjeshta të problemit është të çaktivizosh ngjyrën në ls, por imagjinoni indinjatën e përdoruesve. Nuk duhet të heqim daljen me ngjyra, ne nuk jemi monstruozë.

Prandaj, ne shikuam më thellë. ls përdor ngjyra për shënime përmes variablës së mjedisit LS_COLORS, e cila caktohet nga dircolors(1) në bazë të skedarit të konfiguratës dir_colors(5). Po, skedari ekzekutiv lexon skedarin e konfiguratës për të krijuar variablën e mjedisit, që më pas përdoret nga ls (dhe nëse nuk e dini për skedarët door (do), atëherë dir_colors do të funksionojë, pavarësisht nga gjithçka).

Le të qëndrojmë më në detaje

Për të përcaktuar se cila nga skemat e ngjyrave shkakton ngadalësim, ne krijuam një ambient eksperimental:

$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # mos u përpiqni në shtëpi!
$ time ls --color=always $SCRATCH/dont | wc -l
10000

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

12,7 sekonda për 10 000 skedarë, nuk është shumë mirë.

Për të thënë diçka, nevojitet një flamur --color=always: megjithatë, ai konverton në ls --color=auto, por ls detects kur ai nuk është i lidhur me terminalin (për shembull, përmes kanaleve ose me redirektim) dhe ndalon ngjyrat nëse është vendosur auto. Një djalë i zgjuar.

ÇfarĂ« po e merr aq shumĂ« kohĂ«? Ne e shqyrtuam me 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
[...]

Çudi: 10 000 thirrje lstat(), 10 000 thirrje getxattr() (tĂ« gjitha qĂ« dĂ«shtojnĂ«, sepse nĂ« ambientin tonĂ« nuk ka attribute qĂ« shfrytĂ«zon ls), 10 000 thirrje capget().

Sigurisht që kjo mund të optimizohet.

Atributi capabilities? Jo

Duke ndjekur këshillat e një defekti të para 10 viteve, përpiqem të çaktivizoj kontrollin e atributit 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 total

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

Wow, përshpejtim deri në 8 sekonda! Na shpëtoi nga të gjithë këto thirrje të shtrenjta getxattr(), dhe thirrjet capget() gjithashtu janë zhdukur, shkëlqyer.

Por ende kanĂ« mbetur kĂ«to thirrje tĂ« bezdisshme lstat(), megjithatë 

Sa ngjyrat na nevojiten?

Prandaj, e shqyrtuam më në detaje LS_COLORS.

Fillimisht thjesht e çaktivizuam këtë variabël:

$ 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

ÇfarĂ«!?! PĂ«rsĂ«ri 13 sekonda?

Duket se kur variabla e ambientit LS_COLORS nuk është e përcaktuar ose mungon vetëm një nga elementet e saj =color:, ajo për default përdor një bazë të integruar dhe prapë përdor ngjyrat. Prandaj, nëse dëshiron të çaktivizosh ngjyrat për një lloj të caktuar skedari, duhet ta tejkalosh atë me =: ose 00 në skedarin DIR_COLORS.

Pas shumë provash dhe gabimesh, ne përcaktuam kërkimin deri këtu:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

çfarë regjistrohet si

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

Kjo do të thotë: mos ngjyros skedujt as sipas atributeve capabilities, por sipas bitëve setuid/setgid, as sipas flakës së ekzekutimit.

Shpejtojmë ls

Dhe nëse nuk kryhen asnjë nga këto kontrolle, atëherë thirjet lstat() zhduken, dhe tani është një çështje krejtësisht ndryshe:

$ 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 sekonda në listën e 10,000 skedarëve, rekord.

Rregullojmë Sherlock

Nga 13 sekonda me cilësimet e paracaktuara deri në 0.3 sekonda me një konfigurim të vogël LS_COLORS do të thotë një përshpejtim 40-fish falë mungesës së setuid / setgid dhe skedave ekzekutues të ngjyrosura. Nuk është një humbje aq e madhe.

Sigurisht, tani është e konfigurueshme në Sherlock për çdo përdorues.

Por nëse dëshironi të riktheni ngjyrat, thjesht mund të ktheheni në cilësimet e paracaktuar:

$ unset LS_COLORS

Por atëherë, në katalogët me shumë skeda, sigurohuni të bëni kafe derisa të përfundojë procesi ls.

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster