J'échège un problème dans lequel le cryptage d'un dispositif de bloc impose un énorme Pénalité de performance lorsque écrire. Les heures de lecture et d'expériences sur Internet ne m'ont pas fourni une bonne compréhension, sans parler d'une solution.
La question en bref : Pourquoi est-ce que je reçois des vitesses d'écriture parfaitement rapides lors de la mise sur un dispositif de blocage (~ 170 Mo/s), tandis que la vitesse d'écriture pleure (~ 20 Mo/s) lorsque vous mettez Un DM-Crypt/Luks entre le système de fichiers et le dispositif de bloc, bien que le système soit plus que capable de maintenir un débit de cryptage suffisamment élevé?
/home/schlimmchen/random
est un fichier de 4,0 Go rempli de données de /dev/urandom
plus tôt.
dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096
Lire c'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 lu dans le cache).
L'appareil est directement formaté avec BTRFS (aucune table de partition sur le dispositif de bloc).
$ Sudo mkfs.btrfs /dev/sdf
$ Sudo mount /dev/sdf /mnt
$ Sudo chmod 777 /mnt
La vitesse d'écriture devient jusqu'à ~ 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
L'appareil est formaté avec LUKS et le dispositif 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 souffre que marginalement (pourquoi est-ce tout?):
$ 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
La vitesse d'écriture "Skyrockets" à plus de 150 Mo/s lorsque vous écrivez dans un fichier crypté. Je mettais un fichier BTRF sur le périphérique de bloc, a attribué un fichier de 16 Go, que je lukfsFormat
'ED 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 sont-elles augmentées comme celle-ci? Qu'est-ce que cet imbrication particulier des systèmes de fichiers et des dispositifs de blocage réalisés pour faciliter les vitesses d'écriture élevées?
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 bases vitesses d'écriture avec le noyau 3.19.0 sur System2.
/proc/crypto
pour system1: http://pastebin.com/qusgmfiscryptsetup benchmark
pour system1: http://pastebin.com/4rXzPfetlsblk -t /dev/sdf
: http://pastebin.com/nv49twc--allow-discards
(pour CryptSetup's Luksopen) n'a pas aidé, comme je m'attendais./sys/block/sdf/stat
soutient cette hypothèse depuis que beaucoup d'écritures sont fusionnées. Je suppose donc que l'écriture dans des blocs trop petits n'est pas la cause.La réponse (comme je le sais maintenant): Concurrence .
en bref : mon Ecrivez séquentiel, en utilisant dd
ou lors de la copie d'un fichier (comme ... Dans une utilisation quotidienne), devient A écrit pseudo-aléatoire (mauvais) car quatre threads fonctionnent simultanément sur la rédaction des données cryptées sur le périphérique de bloc après cryptage simultané (bon).
L'effet négatif peut être atténué en augmentant la quantité de demandes en file d'attente dans la file d'attente de planificateur IO comme celle-ci:
echo 4096 | Sudo tee /sys/block/sdc/queue/nr_requests
Dans mon cas, il est presque triple (~ 56 Mo/s) le débit pour le test de données aléatoire de 4 Go expliqué dans ma question. Bien entendu, la performance tombe toujours à 100 Mo/s comparé à l'IO non crypté.
blktrace
J'ai également enquêté sur le scénario problématique dans lequel une BTRFS est placée sur un haut d'un dispositif de bloc crypté LUKS. Pour me montrer quelles instructions d'écriture sont émises sur le périphérique de bloc réel, j'ai utilisé blktrace
comme celui-ci:
Sudo blktrace -a write -d /dev/sdc -o - | blkparse -b 1 -i - | grep -w D
Ce que cela fait est (autant que j'ai pu comprendre) trace IO demande à /dev/sdc
qui sont de type "écrire", puis analysez ceci à la production lisible humaine, mais restreindre davantage La sortie à l'action "[~ # ~] d [~ # ~ ~]", qui est (selon man blkparse
) "io délivré au pilote".
Le résultat était comme celui-ci (voir environ 5000 lignes de sortie du journal multicœur ):
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]
Ceci est une extraction de la sortie produite lors de dd
'ing des données aléatoires de 4 Go sur le système de fichiers monté. Il est clair qu'au moins deux processus sont impliqués. Le journal restant montre que les quatre processeurs y travaillent réellement. Malheureusement, les demandes d'écriture ne sont plus commandées. Bien que la CPU0 écrit quelque part autour du secteur 38038416e, CPU1, qui est prévu après, écrit quelque part autour du secteur 35713872ND. C'est mauvais.
blktrace
J'ai fait la même expérience après avoir désactivé le multi-filetage et la désactivation du deuxième noyau de mon processeur. Bien sûr, un seul processeur est impliqué par écrit sur le bâton. Mais plus important encore, la demande d'écriture sont correctement séquentielles, c'est pourquoi les performances d'écriture complètes d'~ 170 Mo/s sont obtenues dans la même configuration.
Jetez un coup d'œil à environ 5000 lignes de sortie dans le journal SingLecore .
Maintenant que je connais la cause et les termes de recherche Google appropriés, les informations sur ce problème bouillonnent à la surface. Comme il s'avère, je ne suis pas le premier à remarquer.
Parce que je (plus tard) trouvé le Bernel Engage évidemment ciblé à ce problème exact, je voulais essayer un noyau mis à jour. [Après la compilation moi-même, puis découvrez qu'il est déjà dans debian/sid
] Il s'avère que le problème est en effet corrigé. Je ne connais pas la libération exacte du noyau dans laquelle le correctif est apparu, mais le Engagements originaux donner des indices à quiconque intéressé.
Pour le record:
$ 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
Un conseil de chapeau à Mikulas Patocka, qui a rédigé le commit.