Saya sedang menyelidiki masalah di mana mengenkripsi perangkat blok memberikan penalti performa yang sangat besar ketika menulisnya . Jam membaca internet dan eksperimen tidak memberikan saya pemahaman yang tepat, apalagi solusi.
Pertanyaan singkatnya: Mengapa saya mendapatkan kecepatan menulis yang sangat cepat ketika menempatkan btrf ke perangkat blok (~ 170MB / s), sedangkan kecepatan tulis merosot (~ 20MB / s) saat meletakkan dm-crypt / LUKS di antara sistem file dan perangkat blok, meskipun sistem lebih dari mampu mempertahankan throughput enkripsi yang cukup tinggi?
Skenario
/home/schlimmchen/random
adalah file 4.0GB yang diisi dengan data dari /dev/urandom
sebelumnya.
dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096
Membaca sangat cepat:
$ 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
(kedua kalinya, file itu jelas dibaca dari cache).
Btrf tidak terenkripsi
Perangkat langsung diformat dengan btrfs (tidak ada tabel partisi pada perangkat blok).
$ sudo mkfs.btrfs /dev/sdf
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt
Kecepatan tulis setinggi ~ 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
Kecepatan baca jauh di atas 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
Btrf terenkripsi pada perangkat blok
Perangkat diformat dengan LUKS, dan perangkat yang dihasilkan diformat dengan 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
Kecepatan baca hanya mengalami sedikit (mengapa sama sekali?):
$ 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 terenkripsi dalam file pada btrfs pada perangkat blok
Kecepatan tulis "skyrockets" menjadi lebih dari 150MB / s saat menulis ke file yang dienkripsi. Saya meletakkan btrfs ke perangkat blok, mengalokasikan file 16GB, yang saya lukfsFormat
ed dan mount.
$ 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
Mengapa kinerja penulisan meningkat seperti ini? Apa yang dicapai dengan bersarangnya sistem file dan perangkat blok untuk membantu dalam kecepatan penulisan yang tinggi?
Mendirikan
Masalahnya dapat direproduksi pada dua sistem yang menjalankan distro dan kernel yang sama. Namun, saya juga mengamati kecepatan menulis yang rendah dengan kernel 3.19.0 pada System2.
- Perangkat: SanDisk Extreme 64GB USB3.0 USB Stick
- System1: Intel NUC 5i5RYH, i5-5250U (Broadwell), RAM 8GB, Samsung 840 EVO 250GB SSD
- System2: Lenovo T440p, i5-4300M (Haswell), RAM 16GB, Samsung 850 PRO 256GB SSD
- Distro / Kernel: Debian Jessie, 3.16.7
- cryptsetup: 1.6.6
/proc/crypto
untuk System1: http://pastebin.com/QUSGMfiScryptsetup benchmark
untuk System1: http://pastebin.com/4RxzPFeT- btrfs (-tools) adalah versi 3.17
lsblk -t /dev/sdf
: http://pastebin.com/nv49tYWc
Pikiran
- Alignment bukanlah penyebab sejauh yang saya bisa lihat. Bahkan jika ukuran halaman stick adalah 16KiB, awal payload cryptsetup tetap sejalan dengan 2MiB.
--allow-discards
(untuk luksOpen cryptsetup) tidak membantu, seperti yang saya harapkan.- Sambil melakukan eksperimen yang jauh lebih sedikit, saya mengamati perilaku yang sangat mirip dengan hard drive eksternal, yang terhubung melalui adaptor USB3.0.
- Sepertinya saya bahwa sistem ini menulis blok 64KiB. Sebuah naskah systemtrap saya mencoba menunjukkan bahwa setidaknya.
/sys/block/sdf/stat
mendukung hipotesis ini karena banyak penulisan digabung. Jadi tebakan saya adalah bahwa menulis dalam blok yang terlalu kecil bukanlah penyebabnya. - Tidak beruntung dengan mengubah penjadwal antrian perangkat blok ke NOOP.
- Menempatkan crypt ke dalam volume LVM tidak membantu.
sumber
Jawaban:
Jawabannya (seperti yang saya tahu sekarang): concurrency .
Singkatnya : Penulisan sekuensial saya , baik menggunakan
dd
atau ketika menyalin file (seperti ... dalam penggunaan sehari-hari), menjadi penulisan pseudo-acak (buruk) karena empat utas bekerja secara bersamaan untuk menulis data terenkripsi ke perangkat blok setelah bersamaan. enkripsi (baik).Mitigasi (untuk kernel "tua")
Efek negatif dapat dikurangi dengan meningkatkan jumlah permintaan yang antri dalam antrian penjadwal IO seperti ini:
Dalam kasus saya ini hampir tiga kali lipat (~ 56MB / s) throughput untuk tes data acak 4GB dijelaskan dalam pertanyaan saya. Tentu saja, kinerja masih kurang dari 100MB / s dibandingkan dengan IO tidak terenkripsi.
Penyelidikan
Multicore
blktrace
Saya selanjutnya menyelidiki skenario bermasalah di mana btrf ditempatkan di atas perangkat blok terenkripsi LUKS. Untuk menunjukkan kepada saya apa instruksi penulisan yang dikeluarkan untuk perangkat blok aktual, saya menggunakan
blktrace
seperti ini:Apa yang dilakukan adalah (sejauh yang saya bisa mengerti) melacak permintaan IO
/dev/sdc
yang bertipe " tulis ", kemudian parsing ini ke keluaran yang dapat dibaca manusia tetapi lebih jauh membatasi keluaran ke tindakan " D ", yaitu (menurutman blkparse
) " IO dikeluarkan untuk pengemudi ".Hasilnya kira-kira seperti ini (lihat sekitar 5000 baris output dari multicore log ):
Ini adalah potongan dari output yang dihasilkan saat
dd
memasukkan data acak 4GB ke sistem file yang terpasang. Jelas bahwa setidaknya dua proses terlibat. Log yang tersisa menunjukkan bahwa keempat prosesor sebenarnya sedang mengerjakannya. Sayangnya, permintaan tulis tidak dipesan lagi. Sementara CPU0 menulis di sekitar sektor 38038416, CPU1, yang dijadwalkan sesudahnya, menulis di suatu tempat di sekitar sektor 35713872. Itu buruk.Inti tunggal
blktrace
Saya melakukan percobaan yang sama setelah menonaktifkan multi-threading dan menonaktifkan inti kedua CPU saya. Tentu saja, hanya satu prosesor yang terlibat dalam penulisan pada tongkat. Tetapi yang lebih penting, permintaan penulisan berurutan dengan benar, itulah sebabnya kinerja penulisan penuh ~ 170MB / s dicapai dalam pengaturan yang sama.
Lihatlah sekitar 5.000 baris output dalam log singlecore .
Diskusi
Sekarang saya tahu penyebab dan istilah pencarian google yang tepat, informasi tentang masalah ini menggelegak ke permukaan. Ternyata, saya bukan orang pertama yang memperhatikan.
Diperbaiki di kernel saat ini (> = 4.0.2)
Karena saya (kemudian) menemukan komit kernel jelas ditargetkan pada masalah ini, saya ingin mencoba kernel yang diperbarui. [Setelah mengkompilasinya sendiri dan kemudian mengetahuinya sudah ada
debian/sid
] Ternyata masalahnya memang sudah diperbaiki. Saya tidak tahu rilis kernel persis di mana perbaikan muncul, tetapi komit asli akan memberikan petunjuk kepada siapa pun yang tertarik.Untuk catatan:
Tip untuk Mikulas Patocka, yang menulis komit.
sumber