J'étudie un problème où le cryptage d'un périphérique de bloc impose une énorme pénalité de performance lors de l' écriture . Des heures de lecture et d'expériences sur Internet ne m'ont pas permis de bien comprendre, encore moins de trouver une solution.
La question en bref: pourquoi est-ce que j'obtiens des vitesses d'écriture parfaitement rapides lorsque je place un btrfs sur un périphérique de bloc (~ 170 Mo / s), alors que la vitesse d'écriture chute (~ 20 Mo / s) lorsque je place un dm-crypt / LUKS entre les système de fichiers et le périphérique de bloc, bien que le système soit plus que capable de maintenir un débit de cryptage suffisamment élevé?
Scénario
/home/schlimmchen/random
est un fichier de 4,0 Go rempli de données /dev/urandom
antérieures.
dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096
La lecture est super rapide:
$ 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
(la deuxième fois, le fichier a évidemment été lu dans le cache).
Btrfs non chiffrés
Le périphérique est directement formaté avec btrfs (pas de table de partition sur le périphérique bloc).
$ sudo mkfs.btrfs /dev/sdf
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt
La vitesse d'écriture atteint ~ 170 Mo / 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
La vitesse de lecture est bien supérieure à 200 Mo / 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 chiffrés sur périphérique bloc
Le périphérique est formaté avec LUKS et le périphérique résultant est formaté avec 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
La vitesse de lecture ne souffre que marginalement (pourquoi le fait-elle?):
$ 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 chiffrés dans un fichier sur btrfs sur un périphérique bloc
La vitesse d'écriture "monte en flèche" à plus de 150 Mo / s lors de l'écriture dans un fichier crypté. J'ai mis un btrfs sur le périphérique bloc, alloué un fichier de 16 Go, que j'ai lukfsFormat
édité et monté.
$ 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
Pourquoi les performances d'écriture augmentent-elles ainsi? Qu'est-ce que cette imbrication particulière de systèmes de fichiers et de périphériques de blocs permet d'obtenir à des vitesses d'écriture élevées?
Installer
Le problème est reproductible sur deux systèmes exécutant la même distribution et le même noyau. Cependant, j'ai également observé les faibles vitesses d'écriture avec le noyau 3.19.0 sur System2.
- Périphérique: clé USB SanDisk Extreme 64 Go USB 3.0
- System1: Intel NUC 5i5RYH, i5-5250U (Broadwell), 8 Go de RAM, Samsung 840 EVO 250 Go SSD
- System2: Lenovo T440p, i5-4300M (Haswell), 16 Go de RAM, Samsung 850 PRO 256 Go SSD
- Distro / Kernel: Debian Jessie, 3.16.7
- cryptsetup: 1.6.6
/proc/crypto
pour System1: http://pastebin.com/QUSGMfiScryptsetup benchmark
pour System1: http://pastebin.com/4RxzPFeT- btrfs (-tools) est la version 3.17
lsblk -t /dev/sdf
: http://pastebin.com/nv49tYWc
Pensées
- L'alignement n'est pas la cause pour autant que je puisse voir. Même si la taille de page de la clé est de 16 Ko, le début de la charge utile de cryptsetup est de toute façon aligné sur 2 Mo.
--allow-discards
(pour luksOpen de cryptsetup) n'a pas aidé, comme je m'y attendais.- En faisant beaucoup moins d'expériences avec lui, j'ai observé un comportement très similaire avec un disque dur externe, connecté via un adaptateur USB3.0.
- Il me semble que le système écrit des blocs de 64 Ko. Un script systemtrap que j'ai essayé indique au moins cela.
/sys/block/sdf/stat
soutient cette hypothèse car de nombreuses écritures sont fusionnées. Donc, je suppose que l'écriture dans des blocs trop petits n'est pas la cause. - Pas de chance de changer le planificateur de file d'attente de périphérique de bloc en NOOP.
- Mettre la crypte dans un volume LVM n'a pas aidé.