Kad vides mainīgais paātrina procesu 40 reizes

Šodien mēs vēlamies runāt par dažiem jaunākajiem Sherlock sistēmas atjauninājumiem [tas ir augstas veiktspējas klasteris Stenfordas Universitātē — apm. trans.], kas ievērojami paātrina failu uzskaitīšanu direktorijos ar lielu ierakstu skaitu.

Atšķirībā no parastajiem rakstiem šis drīzāk ir iekšējās informācijas ziņojums par to, kā mēs regulāri strādājam ar Sherlock, lai tas lietotājiem nodrošinātu vislabāko darbību. Mēs ceram, ka nākotnē publicēsim vairāk šādu rakstu.

Daudzu failu uzskaitīšana prasa laiku

Viss sākās ar lietotāja tehniskā atbalsta jautājumu. Viņš ziņoja par problēmu, kas saistīta ar izpildi ls aizņem dažas minūtes direktorijā, kurā ir vairāk nekā 15 000 ierakstu $SCRATCH [pagaidu failu direktorijs - apm. josla].

Tūkstošiem failu vienā direktorijā parasti rada slogu failu sistēmai, un tas noteikti nav ieteicams. Lietotājs to zināja un atzina, ka tas nav labi, taču minēja, ka ieraksts viņa klēpjdatorā bija 1000 reižu ātrāks nekā Šerloks. Protams, tas mums kaitēja. Tāpēc mēs skatījāmies dziļāk.

Jo ls izskatās jauki

Mēs apskatījām, ko tas patiesībā dara ls kad tiek uzskaitīts direktorijs, un kāpēc process aizņem tik ilgu laiku. Lielākajā daļā mūsdienu izplatījumu ls pēc noklusējuma tas darbojas kā ls --color=auto, jo visiem patīk krāsas.

Bet skaistām krāsām ir sava cena: katram failam ls jāiegūst informācija par faila tipu, tā atļaujām, karodziņiem, paplašinātajiem atribūtiem un tamlīdzīgi, lai izvēlētos atbilstošo krāsu.

Viens vienkāršs problēmas risinājums ir pilnībā atspējot krāsu ls, taču iedomājieties lietotāju sašutumu. Nekādā gadījumā nedrīkst atņemt krāsu izvadi, mēs neesam briesmoņi.

Tāpēc mēs skatījāmies dziļāk. ls krāsu ieraksti, izmantojot vides mainīgo LS_COLORS, kas ir iestatīts dircolors(1) pamatojoties uz konfigurācijas failu dir_colors(5)... Jā, izpildāmais fails nolasa konfigurācijas failu, lai izveidotu vides mainīgo, ko ls pēc tam izmanto (un, ja jūs nezināt par failiem durvis (darīt), pēc tam dir_colors strādās, Neskatoties uz visu).

Apskatīsim tuvāk

Lai noteiktu, kura krāsu shēma izraisa palēnināšanos, mēs izveidojām eksperimentālu vidi:

$ 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 sekundes 10 000 failiem, ne pārāk labi.

Starp citu, mums vajag karogu --color=always: lai gan viņš pievēršas ls --color=autoBet ls nosaka, kad tas nav savienots ar termināli (piemēram, ar cauruli vai ar izvades novirzīšanu), un atspējo krāsošanu, ja tas ir iestatīts uz auto. Gudrs puisis.

Tātad, kas notiek tik ilgi? Mēs skatījāmies ar 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
[...]

Oho: 10 000 zvanu lstat(), 10 000 zvanu getxattr() (kas viss neizdodas, jo mūsu vidē nav ls meklēto atribūtu), 10 000 zvanu capget().

To noteikti var optimizēt.

Iespējas atribūts? Nē

Ievērojot padomu kļūda pirms 10 gadiem, mēs mēģinājām atspējot atribūtu pārbaudi iespējas:

$ 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

Oho, paātrinājums līdz 8 sekundēm! Mēs atbrīvojāmies no visiem tiem dārgajiem zvaniem getxattr(), un izaicinājumi capget() arī pazuda, lieliski.

Bet joprojām ir šie kaitinošie zvani lstat(), Lai gan…

Cik ziedu jums vajag?

Tāpēc mēs to aplūkojām tuvāk LS_COLORS.

Vispirms mēs vienkārši atspējojām šo mainīgo:

$ 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

Kas!?! Vēl 13 sekundes?

Izrādās, ka tad, kad vides mainīgais LS_COLORS tikai viens no tā elementiem nav definēts vai tā trūkst <type>=color:, tā pēc noklusējuma izmanto iebūvēto datu bāzi un joprojām izmanto krāsas. Tātad, ja vēlaties atspējot iekrāsošanu noteiktam faila tipam, tas ir jāignorē ar <type>=: vai <type> 00 failā DIR_COLORS.

Pēc daudziem izmēģinājumiem un kļūdām mēs sašaurinājām meklēšanu līdz šim:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

kas ir rakstīts kā

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

Tas nozīmē: nekrāsojiet failus pēc atribūta. iespējas, bet pamazām setuid/setgid, ne ar izpildāmības karodziņš.

Mēs paātrinām ls

Un, ja jūs neveicat nevienu no šīm pārbaudēm, tad zvaniet lstat() pazūd, un tagad tas ir pavisam cits jautājums:

$ 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 sekundes 10 000 failu sarakstā, rekords.

Šerloka iestatīšana

No 13 sekundēm ar noklusējuma iestatījumiem līdz 0,3 sekundēm ar nelielām korekcijām LS_COLORS nozīmē 40-kārtīgu paātrinājumu prombūtnes dēļ setuid / setgid un krāsainos izpildāmos failus. Nav tik liels zaudējums.

Protams, tagad tas ir konfigurēts Sherlock katram lietotājam.

Bet, ja vēlaties atgriezt krāsojumu, varat vienkārši atgriezties pie noklusējuma iestatījumiem:

$ unset LS_COLORS

Bet pēc tam direktorijos ar daudziem failiem noteikti pagatavojiet kafiju, kamēr tā darbojas ls.

Avots: www.habr.com

Pievieno komentāru