Apabila pembolehubah persekitaran mempercepatkan proses sebanyak 40 kali ganda

Hari ini kita ingin bercakap tentang beberapa kemas kini terkini kepada sistem Sherlock [ini ialah kluster berprestasi tinggi di Universiti Stanford - lebih kurang. trans.], yang mempercepatkan penyenaraian fail dalam direktori dengan jumlah entri yang banyak.

Tidak seperti artikel biasa, ini lebih kepada laporan orang dalam tentang cara kami kerap mengusahakan Sherlock untuk memastikan ia berjalan pada tahap terbaik untuk pengguna kami. Kami berharap untuk menerbitkan lebih banyak artikel seperti ini pada masa akan datang.

Menyenaraikan banyak fail memerlukan masa

Semuanya bermula dengan soalan sokongan teknikal daripada pengguna. Beliau melaporkan masalah bahawa pelaksanaan ls mengambil masa beberapa minit dalam direktori dengan lebih 15 entri masuk $SCRATCH [direktori untuk fail sementara - lebih kurang. lorong].

Beribu-ribu fail dalam satu direktori biasanya menimbulkan beban kepada sistem fail dan pastinya tidak disyorkan. Pengguna mengetahui perkara ini dan mengakui bahawa ia tidak bagus, tetapi menyebut penyenaraian itu 1000 kali lebih pantas pada komputer ribanya berbanding Sherlock. Sudah tentu, ini menyakitkan kami. Jadi kami melihat lebih dalam.

Kerana ls kelihatan baik

Kami melihat apa yang sebenarnya dilakukannya ls apabila menyenaraikan direktori, dan mengapa proses itu mengambil masa yang lama. Pada kebanyakan pengedaran moden ls secara lalai ia berjalan sebagai ls --color=auto, kerana semua orang suka warnanya.

Tetapi warna yang cantik datang pada harga: untuk setiap fail ls mesti mendapatkan maklumat tentang jenis fail, kebenarannya, bendera, atribut lanjutan dan seumpamanya untuk memilih warna yang sesuai.

Satu penyelesaian mudah untuk masalah ini adalah untuk melumpuhkan warna dalam ls sama sekali, tetapi bayangkan kemarahan pengguna. Dalam apa jua keadaan, anda tidak boleh mengambil keluaran warna, kami bukan raksasa.

Jadi kami melihat lebih dalam. ls entri warna melalui pembolehubah persekitaran LS_COLORS, yang ditetapkan dircolors(1) berdasarkan fail konfigurasi dir_colors(5)... Ya, boleh laku membaca fail konfigurasi untuk mencipta pembolehubah persekitaran, yang kemudiannya digunakan (dan jika anda tidak tahu tentang fail pintu (buat), kemudian dir_colors akan bekerja, Walaupun segala-galanya).

Mari kita lihat lebih dekat

Untuk menentukan skema warna yang menyebabkan kelembapan, kami mencipta persekitaran percubaan:

$ 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 saat untuk 10 fail, tidak begitu baik.

By the way, kita perlukan bendera --color=always: walaupun dia beralih kepada ls --color=autoTetapi ls mengesan apabila ia tidak disambungkan ke terminal (cth. melalui paip atau dengan pengalihan semula keluaran) dan melumpuhkan pewarnaan jika ditetapkan kepada auto. Lelaki pandai.

Jadi apa yang mengambil masa yang lama? Kami melihat dengan 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
[...]

Wow: 10 panggilan lstat(), 10 panggilan getxattr() (yang semuanya gagal kerana persekitaran kita tidak mempunyai atribut yang ls cari), 10 panggilan capget().

Sudah tentu ini boleh dioptimumkan.

Atribut keupayaan? Tidak

Mengikut nasihat pepijat sejak 10 tahun lalu, kami cuba melumpuhkan semakan atribut keupayaan:

$ 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

Wah, sehingga 8 saat pecutan! Kami telah menyingkirkan semua panggilan mahal itu getxattr(), dan cabaran capget() hilang juga, hebat.

Tetapi masih ada panggilan yang menjengkelkan ini lstat(), Walaupun…

Berapa banyak bunga yang anda perlukan?

Oleh itu, kami melihat lebih dekat LS_COLORS.

Mula-mula kami hanya melumpuhkan pembolehubah ini:

$ 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

Apa!?! Masih 13 saat?

Ternyata apabila pembolehubah persekitaran LS_COLORS hanya satu daripada elemennya tidak ditakrifkan atau hilang <type>=color:, ia menggunakan pangkalan data terbina dalam secara lalai dan masih menggunakan warna. Jadi, jika anda ingin melumpuhkan pewarnaan untuk jenis fail tertentu, anda perlu mengatasinya <type>=: atau <type> 00 dalam fail DIR_COLORS.

Selepas banyak percubaan dan kesilapan, kami mengecilkan carian kami kepada ini:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

yang ditulis sebagai

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

Ini bermakna: jangan warnakan fail mengikut atribut. keupayaan, tetapi sedikit demi sedikit setuid/setgid, tidak juga oleh bendera kebolehlaksanaan.

Kami mempercepatkan ls

Dan jika anda tidak melakukan mana-mana pemeriksaan ini, maka hubungi lstat() hilang, dan kini ia adalah perkara yang sama sekali berbeza:

$ 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 saat pada senarai 10 fail, satu rekod.

Menyediakan Sherlock

Daripada 13 saat dengan tetapan lalai kepada 0,3 saat dengan pelarasan kecil LS_COLORS bermakna pecutan 40 kali ganda kerana ketiadaan setuid / setgid dan fail boleh laku berwarna. Bukan kerugian yang besar.

Sudah tentu, ini kini dikonfigurasikan dalam Sherlock untuk setiap pengguna.

Tetapi jika anda ingin mengembalikan pewarnaan, anda boleh kembali ke tetapan lalai:

$ unset LS_COLORS

Tetapi kemudian pada direktori dengan banyak fail, pastikan anda membancuh kopi semasa ia berjalan ls.

Sumber: www.habr.com

Tambah komen