Я исследую проблему, когда шифрование блочного устройства приводит к огромным потерям производительности при записи на него. Часы чтения в Интернете и эксперименты не дали мне правильного понимания, не говоря уже о решении.
Короче вопрос: почему я получаю совершенно высокие скорости записи при помещении btrfs на блочное устройство (~ 170 МБ / с), в то время как скорость записи резко падает (~ 20 МБ / с) при установке dm-crypt / LUKS между файловая система и блочное устройство, хотя система более чем способна поддерживать достаточно высокую пропускную способность шифрования?
сценарий
/home/schlimmchen/random
файл объемом 4,0 ГБ, заполненный данными из /dev/urandom
предыдущих
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
(второй раз файл явно читался из кеша).
Незашифрованные btrfs
Устройство напрямую отформатировано с помощью btrfs (нет таблицы разделов на блочном устройстве).
$ sudo mkfs.btrfs /dev/sdf
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt
Скорость записи достигает ~ 170 МБ / с:
$ 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
Скорость чтения значительно выше 200 МБ / с.
$ 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 на блочном устройстве
Скорость записи увеличивается до 150 МБ / с при записи в зашифрованный файл. Я поместил btrfs на блочное устройство, выделил файл 16 ГБ, который я 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
Почему производительность записи увеличивается так? Чего добивается эта конкретная вложенность файловых систем и блочных устройств для обеспечения высокой скорости записи?
Настроить
Проблема воспроизводима на двух системах, работающих под управлением одного и того же дистрибутива и ядра. Однако я также наблюдал низкие скорости записи с ядром 3.19.0 на System2.
- Устройство: USB-накопитель SanDisk Extreme 64 ГБ USB3.0
- Система 1: Intel NUC 5i5RYH, i5-5250U (Broadwell), 8 ГБ ОЗУ, Samsung 840 EVO, 250 ГБ SSD
- Система2: Lenovo T440p, i5-4300M (Haswell), 16 ГБ ОЗУ, Samsung 850 PRO, 256 ГБ 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
мысли
- Выравнивание не причина, насколько я вижу. Даже если размер страницы флешки составляет 16 КБ, начало полезной нагрузки cryptsetup в любом случае выравнивается до 2 МБ.
--allow-discards
(для luksOpen cryptsetup) не помогло, как я ожидал.- Проводя с ним гораздо меньше экспериментов, я наблюдал очень похожее поведение с внешним жестким диском, подключенным через адаптер USB3.0.
- Мне кажется, что система записывает блоки по 64 КБ. Systemtrap сценарий я попытался показывает , что по крайней мере.
/sys/block/sdf/stat
подтверждает эту гипотезу, поскольку многие записи объединены. Таким образом, я предполагаю, что письмо в слишком маленьких блоках не является причиной. - Не повезло с изменением планировщика очереди блочных устройств на NOOP.
- Помещение склепа в том LVM не помогло.
источник
Ответы:
Ответ (как я теперь знаю): параллелизм .
Вкратце : моя последовательная запись с использованием
dd
или при копировании файла (например ... при ежедневном использовании) становится псевдослучайной записью (плохо), поскольку четыре потока одновременно работают над записью зашифрованных данных на блочное устройство после одновременной шифрование (хорошо).Смягчение (для «старых» ядер)
Негативный эффект можно уменьшить, увеличив количество запросов в очереди в очереди планировщика ввода-вывода, например:
В моем случае это почти утроило (~ 56 МБ / с) пропускную способность для теста случайных данных 4 ГБ, объясненного в моем вопросе. Конечно, производительность по-прежнему ниже 100 МБ / с по сравнению с незашифрованным вводом-выводом.
изучение
многожильный
blktrace
Кроме того, я исследовал проблемный сценарий, в котором btrfs помещается поверх зашифрованного блочного устройства LUKS. Чтобы показать мне, какие инструкции по записи выдаются фактическому блочному устройству, я использовал
blktrace
это так:Что это делает (насколько я смог понять), проследить запрос ввода-вывода,
/dev/sdc
которые имеют тип " запись », затем анализировать его для читабельного вывода, но далее ограничивать вывод действием « D », которое (согласноman blkparse
) « IO выдан водителю ».Результат был примерно таким (см. Около 5000 строк вывода многожильного журнала ):
Это фрагмент выходных данных, полученных при записи
dd
случайных данных 4 ГБ в смонтированную файловую систему. Понятно, что участвуют как минимум два процесса. Оставшийся журнал показывает, что все четыре процессора фактически работают над ним. К сожалению, запросы на запись больше не упорядочены. В то время как CPU0 записывает где-то около 38038416-го сектора, CPU1, который запланирован позже, записывает где-то около 35713872-го сектора. Плохо.Singlecore
blktrace
Я сделал тот же эксперимент после отключения многопоточности и отключения второго ядра моего процессора. Конечно, только один процессор участвует в записи на флешку. Но что еще более важно, запрос на запись является правильно последовательным, поэтому полная производительность записи ~ 170 МБ / с достигается в остальных случаях.
Посмотрите на около 5000 строк вывода в одноядерном журнале .
обсуждение
Теперь, когда я знаю причину и правильные условия поиска в Google, информация об этой проблеме всплывает на поверхность. Оказывается, я не первый, кто замечает.
Исправлено в текущих ядрах (> = 4.0.2)
Поскольку (позже) я обнаружил, что коммит ядра явно предназначен именно для этой проблемы, я хотел попробовать обновленное ядро. [После того, как он сам скомпилирован, а затем обнаружил, что он уже есть
debian/sid
] Оказывается, проблема действительно решена. Я не знаю точную версию ядра, в которой появилось исправление, но оригинальный коммит даст подсказки всем, кто заинтересован.Для записи:
Шляпная шапка Микулашу Патоцке, который написал коммит.
источник