ブロックデバイスを暗号化すると、書き込み時にパフォーマンスが大幅に低下する問題を調査しています。インターネットで何時間も読んだり実験したりしても、解決策は言うまでもなく、適切な理解が得られませんでした。
要するに、ブロックデバイスにbtrfsを入れると書き込み速度が完全に速くなる(〜170MB / s)のに、dm-crypt / LUKSを入れると書き込み速度が急落する(〜20MB / s)ファイルシステムとブロックデバイス。ただし、システムは十分に高い暗号化スループットを維持できますか?
シナリオ
/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
luksDump: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
書き込みパフォーマンスがこのように向上するのはなぜですか?ファイルシステムとブロックデバイスのこの特定のネストは、高速書き込みを支援するために何を達成しますか?
セットアップ
この問題は、同じディストリビューションとカーネルを実行する2つのシステムで再現可能です。ただし、System2のカーネル3.19.0では書き込み速度が遅いことも確認しました。
- デバイス:SanDisk Extreme 64GB USB3.0 USB Stick
- システム1:Intel NUC 5i5RYH、i5-5250U(Broadwell)、8GB RAM、Samsung 840 EVO 250GB SSD
- System2:Lenovo T440p、i5-4300M(Haswell)、16GB RAM、Samsung 850 PRO 256GB SSD
- ディストリビューション/カーネル:Debian Jessie、3.16.7
- cryptsetup:1.6.6
/proc/crypto
System1の場合:http ://pastebin.com/QUSGMfiScryptsetup benchmark
System1の場合: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ボリュームに暗号を入れることは役に立ちませんでした。