環境変数によってプロセスが 40 倍高速化される場合

今日は、Sherlock システムの最新のアップデートのいくつかについて話したいと思います [これはスタンフォード大学の高性能クラスターです。 trans.] を使用すると、多数のエントリを含むディレクトリ内のファイルの一覧表示が大幅に高速化されます。

通常の記事とは異なり、これは、Sherlock をユーザーにとって最高の状態で実行し続けるために、私たちがどのように定期的に取り組んでいるかについての内部関係者のレポートです。 今後もこのような記事をもっと公開していきたいと考えています。

多くのファイルをリストするには時間がかかります

すべてはユーザーからのテクニカル サポートの質問から始まりました。 彼は処刑が行われるという問題を報告した ls 15 を超えるエントリがあるディレクトリでは数分かかります $SCRATCH [一時ファイル用ディレクトリ - 約レーン]。

1000 つのディレクトリに数千のファイルがあると、通常、ファイル システムに負担がかかるため、絶対にお勧めできません。 ユーザーはこれを知っており、それが良くないことを認めましたが、ラップトップではリストがシャーロックよりも XNUMX 倍速かったと述べました。 もちろん、これは私たちを傷つけました。 そこで、さらに詳しく調べてみました。

見た目が素敵だから

実際に何をするのか調べてみました ls ディレクトリをリストするときと、そのプロセスに時間がかかる理由について説明します。 ほとんどの最新のディストリビューションでは ls デフォルトでは次のように実行されます ls --color=auto、みんな色が好きなので。

しかし、美しい色には、ファイルごとに代償が伴います。 ls 適切な色を選択するには、ファイルの種類、そのアクセス許可、フラグ、拡張属性などに関する情報を取得する必要があります。

この問題に対する簡単な解決策の XNUMX つは、ls でカラーを完全に無効にすることですが、ユーザーからの怒りを想像してみてください。 いかなる状況であっても、カラー出力を取り上げてはなりません。私たちはモンスターではありません。

そこで、さらに詳しく調べてみました。 ls 環境変数を介した色のエントリ LS_COLORS、設定されています dircolors(1) 構成ファイルに基づいて dir_colors(5)。 はい、 実行可能ファイルは構成ファイルを読み取って環境変数を作成し、それを使用します。 (ファイルについてわからない場合は、 ドア (する)、次に dir_colors 働くでしょう、すべてにもかかわらず)。

もっと詳しく見てみましょう

どの配色が速度低下の原因となっているかを判断するために、実験環境を作成しました。

$ 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 ファイルの場合は 10 秒で、あまり良いとは言えません。

ところで、旗が必要です --color=always:彼は振り返ったものの、 ls --color=autoしかし ls 端末に接続されていないことを検出し (パイプや出力リダイレクトなど)、設定されている場合はカラーリングを無効にします。 auto。 賢い奴だ。

それで、何がそんなに時間がかかるのでしょうか? 一緒に見ました 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
[...]

すごい: 10 回の通話 lstat()、10 回の通話 getxattr() (私たちの環境には ls が探している属性がないため、すべて失敗します)、10 回の呼び出し capget().

確かにこれは最適化できます。

能力属性? いいえ

アドバイスに従ってください 10年前のバグ、属性チェックを無効にしてみました 機能:

$ 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

なんと、最大8秒の加速! 高額な通話はすべて廃止しました getxattr()、そして課題 capget() も消えた、すごい。

しかし、迷惑電話はまだあります lstat()、 それでも…

花は何本必要ですか?

そこで、さらに詳しく調べてみました LS_COLORS.

まず、この変数を単純に無効にしました。

$ 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

何!?! まだ13秒くらい?

環境変数が LS_COLORS 要素の XNUMX つだけが定義されていないか欠落しています <type>=color:、デフォルトで組み込みデータベースを使用し、引き続き色を使用します。 したがって、特定のファイルタイプの色付けを無効にしたい場合は、それを次のようにオーバーライドする必要があります。 <type>=: または <type> 00 ファイル内 DIR_COLORS.

多くの試行錯誤の結果、検索結果を以下に絞り込みました。

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

これは次のように書かれています

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

これは、ファイルを属性ごとに色付けしないことを意味します。 機能、でも少しずつ setuid/setgid、どちらによっても 実行可能フラグ.

スピードアップします ls

これらのチェックをいずれも実行しない場合は、 lstat() 消えてしまい、今度はまったく別の問題になります。

$ 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 ファイルのリストでは 10 秒という記録です。

シャーロックのセットアップ

デフォルト設定の 13 秒から微調整で 0,3 秒まで LS_COLORS 存在しないことによる 40 倍の加速を意味します。 setuid / setgid および色付きの実行可能ファイル。 そんなに大きな損失ではありません。

もちろん、これは各ユーザーの Sherlock で設定されます。

ただし、色を元に戻したい場合は、単にデフォルト設定に戻すことができます。

$ unset LS_COLORS

ただし、多くのファイルが含まれるディレクトリでは、実行中に必ずコーヒーを淹れるようにしてください。 ls.

出所: habr.com

コメントを追加します