Ketika variabel lingkungan mempercepat proses sebanyak 40 kali lipat

Hari ini kami ingin membicarakan beberapa pembaruan terkini pada sistem Sherlock [ini adalah cluster berkinerja tinggi di Universitas Stanford - kira-kira. trans.], yang secara signifikan mempercepat pencatatan file di direktori dengan jumlah entri yang banyak.

Tidak seperti artikel biasa, artikel ini lebih merupakan laporan orang dalam tentang bagaimana kami secara rutin mengerjakan Sherlock agar tetap berjalan sebaik mungkin bagi pengguna kami. Kami berharap dapat menerbitkan lebih banyak artikel seperti ini di masa mendatang.

Mendaftar banyak file membutuhkan waktu

Semuanya dimulai dengan pertanyaan dukungan teknis dari pengguna. Dia melaporkan masalah eksekusi itu ls membutuhkan waktu beberapa menit dalam direktori dengan lebih dari 15 entri $SCRATCH [direktori untuk file sementara - kira-kira. jalur].

Ribuan file dalam satu direktori biasanya membebani sistem file dan tentunya tidak disarankan. Pengguna mengetahui hal ini dan mengakui bahwa itu tidak bagus, tetapi menyebutkan bahwa listingan di laptopnya 1000 kali lebih cepat daripada Sherlock. Tentu saja hal ini merugikan kami. Jadi kami melihat lebih dalam.

Karena aku terlihat bagus

Kami melihat apa yang sebenarnya dilakukannya ls saat membuat daftar direktori, dan mengapa prosesnya memakan waktu lama. Pada sebagian besar distribusi modern ls secara default ini berjalan sebagai ls --color=auto, karena semua orang menyukai warnanya.

Namun warna-warna indah ada harganya: untuk setiap file ls harus memperoleh informasi tentang jenis file, izinnya, bendera, atribut yang diperluas, dan sejenisnya untuk memilih warna yang sesuai.

Salah satu solusi sederhana untuk masalah ini adalah dengan menonaktifkan warna di ls sama sekali, tapi bayangkan kemarahan pengguna. Dalam situasi apa pun Anda tidak boleh menghilangkan keluaran warna, kami bukan monster.

Jadi kami melihat lebih dalam. ls entri warna melalui variabel lingkungan LS_COLORS, yang sudah diatur dircolors(1) berdasarkan file konfigurasi dir_colors(5)... Ya, executable membaca file konfigurasi untuk membuat variabel lingkungan, yang kemudian digunakan ls (dan jika Anda tidak tahu tentang file pintu (lakukan), lalu dir_colors akan bekerja, Terlepas dari segalanya).

Mari kita lihat lebih dekat

Untuk menentukan skema warna mana yang menyebabkan pelambatan, kami membuat lingkungan eksperimental:

$ 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 detik untuk 10 file, tidak terlalu bagus.

Ngomong-ngomong, kita butuh bendera --color=always: meskipun dia menoleh ke ls --color=autoTetapi ls mendeteksi ketika tidak terhubung ke terminal (misalnya melalui pipa atau dengan pengalihan keluaran) dan menonaktifkan pewarnaan jika diatur ke auto. Pria pintar.

Jadi kenapa lama sekali? 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 karena lingkungan kita tidak memiliki atribut yang dicari ls), 10 panggilan capget().

Tentunya hal ini bisa dioptimalkan.

Atribut kemampuan? Tidak

Mengikuti saran bug dari 10 tahun yang lalu, kami mencoba menonaktifkan pemeriksaan atribut kemampuan:

$ 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, akselerasinya hingga 8 detik! Kami menyingkirkan semua panggilan mahal itu getxattr(), dan tantangan capget() menghilang juga, bagus.

Namun masih ada panggilan-panggilan yang mengganggu lstat(), Meskipun…

Berapa banyak bunga yang Anda butuhkan?

Oleh karena itu, kami melihat lebih dekat LS_COLORS.

Pertama kita cukup menonaktifkan variabel 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 detik?

Ternyata ketika variabel lingkungan LS_COLORS hanya satu elemennya yang tidak terdefinisi atau hilang <type>=color:, ia menggunakan database bawaan secara default dan masih menggunakan warna. Jadi jika Anda ingin menonaktifkan pewarnaan untuk jenis file tertentu, Anda perlu menggantinya dengan <type>=: ΠΈΠ»ΠΈ <type> 00 dalam file DIR_COLORS.

Setelah banyak percobaan dan kesalahan, kami mempersempit pencarian kami menjadi ini:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

yang ditulis sebagai

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

Artinya: jangan mewarnai file berdasarkan atribut. kemampuan, tapi sedikit demi sedikit setuid/setgid, tidak juga oleh bendera eksekusi.

Kami mempercepat ls

Dan jika Anda tidak melakukan pemeriksaan ini, teleponlah lstat() menghilang, dan sekarang masalahnya benar-benar berbeda:

$ 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 detik pada daftar 10 file, sebuah rekor.

Menyiapkan Sherlock

Dari 13 detik dengan pengaturan default hingga 0,3 detik dengan sedikit penyesuaian LS_COLORS berarti percepatan 40 kali lipat karena ketidakhadiran setuid / setgid dan file executable berwarna. Kerugiannya tidak begitu besar.

Tentu saja, ini sekarang dikonfigurasi di Sherlock untuk setiap pengguna.

Namun jika ingin mengembalikan pewarnaannya, Anda cukup kembali ke pengaturan default:

$ unset LS_COLORS

Namun pada direktori dengan banyak file, pastikan untuk menyeduh kopi saat sedang berjalan ls.

Sumber: www.habr.com

Tambah komentar