LUKS(Universal dm-crypt)書き込み性能が悪い

LUKS(Universal dm-crypt)書き込み性能が悪い

暗号化されたブロックデバイス巨大な性能損失書くそれに。何時間もWebを読んで実験しても、解決策はどこでも適切な理解を得ませんでした。

簡単に言うと:btrfsをブロックデバイスに入れると、非常に高速な書き込み速度(〜170MB / s)が得られますが、ファイルシステムとブロック(〜20MB / s)デバイスの間にdm-crypt / LUKSを置くとなぜ急落しますか?システムが十分に高い暗号スループットを維持するのに十分ですか?

想像する

/home/schlimmchen/random/dev/urandom初期データが入った4.0GBファイルです。

dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096

読み取り速度が非常に高速です。

$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 6.58036 s, 648 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 0.786102 s, 5.4 GB/s

(2番目にキャッシュからファイルを読み込んだようです。)

暗号化されていないbtrfs

デバイスはbtrfsとして直接フォーマットされます(ブロックデバイスにはパーティションテーブルはありません)。

$ sudo mkfs.btrfs /dev/sdf
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt

最大170MB / sの書き込み速度:

$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.1564 s, 157 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 25.1882 s, 169 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test3 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 29.8419 s, 143 MB/s

読み取り速度は200MB / sをはるかに上回ります。

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8265 s, 215 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.9821 s, 213 MB/s
$ dd if=/mnt/dd-test3 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8561 s, 215 MB/s

ブロックデバイスの暗号化されたbtrfs

LUKSを使用してデバイスをフォーマットし、btrfsを使用して結果デバイスをフォーマットします。

$ sudo cryptsetup luksFormat /dev/sdf
$ sudo cryptsetup luksOpen /dev/sdf crypt
$ sudo mkfs.btrfs /dev/mapper/crypt
$ sudo mount /dev/mapper/crypt /mnt
$ sudo chmod 777 /mnt
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 210.42 s, 20.3 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M 
4265841146 bytes (4.3 GB) copied, 207.402 s, 20.6 MB/s

読み取り速度はわずかに影響を受けます(理由は何ですか?)。

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.2002 s, 192 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.0794 s, 193 MB/s

ルクスダンプ:http://pastebin.com/i9VYRR0p

ブロックデバイスのbtrfs内のファイルの暗号化btrfs

暗号化されたファイルを書き込むと、書き込み速度は150MB / s以上に「急増」しました。ブロックデバイスにbtrfsを挿入し、16GBのファイルを割り当て、編集してlukfsFormatマウントしました。

$ sudo mkfs.btrfs /dev/sdf -f
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt
$ dd if=/dev/zero of=/mnt/crypted-file bs=1M count=16384 conv=fsync
17179869184 bytes (17 GB) copied, 100.534 s, 171 MB/s
$ sudo cryptsetup luksFormat /mnt/crypted-file
$ sudo cryptsetup luksOpen /mnt/crypted-file crypt
$ sudo mkfs.btrfs /dev/mapper/crypt
$ sudo mount /dev/mapper/crypt /tmp/nested/
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 26.4524 s, 161 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.5601 s, 155 MB/s

なぜこのように書き込みパフォーマンスが良くなるのですか?書き込み速度を向上させるために、ファイルシステムとブロックデバイスを特別にネストすると何が得られますか?

設定

この問題は、同じディストリビューションとカーネルを実行する両方のシステムで再現可能です。しかし、System2のカーネル3.19.0では、書き込み速度が遅くなることも観察されました。

  • デバイス: SanDisk Extreme 64GB USB3.0 USB メモリースティック
  • システム1:Intel NUC 5i5RYH、i5-5250U(Broadwell)、8GB RAM、Samsung 840 EVO 250GB SSD
  • システム2:Lenovo T440p、i5-4300M(Haswell)、16GB RAM、Samsung 850 PRO 256GB SSD
  • ディストリビューション/カーネル: Debian Jessie, 3.16.7
  • パスワード設定:1.6.6
  • /proc/cryptoシステム1の場合:http://pastebin.com/QUSGMfiS
  • cryptsetup benchmarkシステム1の場合:http://pastebin.com/4RxzPFeT
  • btrfs(-tools) バージョンは 3.17 です。
  • lsblk -t /dev/sdf:http://pastebin.com/nv49tYWc

アイデア

  • ソートはいいえ私が知る限り、その理由は。スティックのページサイズが16KiBの場合でも、cryptsetupペイロードの開始は2MiBにソートされます。
  • --allow-discards(cryptsetupのluksOpen)は期待どおりに役に立ちません。
  • 実験したことはありませんが、USB3.0アダプタを介して接続された外付けハードドライブが非常に似ていることを観察しました。
  • 私が見るには、システムが64KiBブロックを書いているようです。 ㅏシステムトラップスクリプト私は少なくともそれが本当であることを示すために努力します。/sys/block/sdf/statこの仮説は、多数の書き込みがマージされるために裏付けられています。だから私の考えでは、小さすぎるブロックを書くことが原因ではないようです。
  • ブロックデバイスキュースケジューラをNOOPに変更できませんでした。
  • LVMボリュームに暗号化を入れることは役に立ちません。

ベストアンサー1

答え(現在私が知っている限り):並行性

要するに:私のもの順次書き込みddファイルを使用またはコピーする場合(例:日常的な使用)擬似乱数を書く(悪い)4つのスレッドが同時に動作するため、ブロックデバイスに同時に暗号化された暗号化データを書き込みます(良い)。

緩和策(「以前」カーネルの場合)

次のように、IOスケジューラキューで待機している要求の数を増やすことで、悪影響を軽減できます。

echo 4096 | sudo tee /sys/block/sdc/queue/nr_requests

私の場合、これは私の質問で説明されている4 GBのランダムデータテストスループット(〜56 MB / s)のほぼ3倍に相当します。もちろん、暗号化されていないIOと比較して、パフォーマンスはまだ100 MB / s未満です。

調査

マルチコアblktrace

LUKS暗号化ブロックデバイスの上にbtrfsを配置する問題のシナリオをさらに調査しました。実際のブロックデバイスにどの書き込みコマンドが発行されたかを示すために、次のようなblktraceものを使用しました。

sudo blktrace -a write -d /dev/sdc -o - | blkparse -b 1 -i - | grep -w D

私が理解できる限り、この機能が何をするのか/dev/sdc書くその後、これを人間が読める出力に解析しますが、出力をさらに操作に制限します。D「これは(によるとman blkparse)」IOがドライバーに送信されました」。

結果はこんな感じです(参考マルチコアログ出力は約5000行です。):

8,32   0    32732   127.148240056     3  D   W 38036976 + 240 [ksoftirqd/0]
8,32   0    32734   127.149958221     3  D   W 38038176 + 240 [ksoftirqd/0]
8,32   0    32736   127.160257521     3  D   W 38038416 + 240 [ksoftirqd/0]
8,32   1    30264   127.186905632    13  D   W 35712032 + 240 [ksoftirqd/1]
8,32   1    30266   127.196561599    13  D   W 35712272 + 240 [ksoftirqd/1]
8,32   1    30268   127.209431760    13  D   W 35713872 + 240 [ksoftirqd/1]
  • 最初の列:ブロックデバイスのメジャーとマイナー
  • 列 2: CPU ID
  • 列 3: シリアル番号
  • 列 4: タイムスタンプ
  • 列5:プロセスID
  • 列 6: アクション
  • 列7:RWBSデータ(タイプ、セクタ、長さ)

ddこれは、マウントされたファイルシステムに4 GBのランダムデータをロードしたときに生成される出力の断片です。明らかに、少なくとも2つのプロセスが関連している。残りのログは、4つのプロセッサがすべて実際に処理していることを示しています。残念ながら、書き込み要求はソートされなくなりました。 CPU0 がセクター 38038416 の近くに書き込まれている間、後で予約された CPU1 は、セクター 35713872 の近くに書き込みます。その悪い。

シングルコアblktrace

マルチスレッドを無効にしてCPUの2番目のコアを無効にした後、同じ実験を行いました。もちろん、スティック書き込みには1つのプロセッサのみが使用されます。しかし、もっと重要なのは、書き込み要求の順序が正しく指定されているため、同じ設定で約170 MB / sの完全な書き込みパフォーマンスが達成されたことです。

見るシングルコアログ出力は約5,000行です。

議論する

これで原因と正しいGoogleクエリがわかったので、この問題に関する情報が表示されました。知っていると、私はこれを初めて気づいた人ではありません。

現在のカーネルで修正済み(>=4.0.2)

なぜなら、私は(後で)知っていたからです。カーネルコミット明らかにこの問題のため、私は最新のカーネルを試してみたかったです。 [直接コンパイルしてみるとすでに存在していましたdebian/sid。] 実際に問題が解決されたことがわかりました。修正が正確にどのカーネルバージョンに表示されるかはわかりませんが、元のコミット興味のある方にリードが提供されます。

参考までに:

$ uname -a
Linux t440p 4.0.0-1-amd64 #1 SMP Debian 4.0.2-1 (2015-05-11) x86_64 GNU/Linux
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test bs=1M conv=fsync
4294967296 bytes (4.3 GB) copied, 29.7559 s, 144 MB/s

この投稿の作成者であるMikulas Patockaに送信する帽子のヒントです。

おすすめ記事