Абісмальна загальна dm-крипта (LUKS) виконання запису


21

Я розслідую проблему, коли шифрування блочного пристрою накладає величезну штрафну ефективність при його написанні . Години читання в Інтернеті та експериментів не дали мені належного розуміння, не кажучи вже про рішення.

Питання коротше: Чому я отримую ідеально швидкі швидкості запису при покладенні btrfs на блоковий пристрій (~ 170 Мб / с), тоді як швидкість запису падає (~ 20 Мб / с), коли ставлять dm-крипту / 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.

  • Пристрій: SanDisk Extreme 64GB USB3.0 USB-накопичувач
  • System1: Intel NUC 5i5RYH, i5-5250U (Broadwell), 8 Гб оперативної пам’яті, Samsung 840 EVO 250GB SSD
  • System2: Lenovo T440p, i5-4300M (Haswell), 16 Гб оперативної пам’яті, Samsung 850 PRO 256 ГБ SSD
  • Distro / Kernel: Debian Jessie, 3.16.7
  • криптовалюта: 1.6.6
  • /proc/cryptoдля System1: http://pastebin.com/QUSGMfiS
  • cryptsetup benchmarkдля System1: http://pastebin.com/4RxzPFeT
  • btrfs (-tools) - версія 3.17
  • lsblk -t /dev/sdf: http://pastebin.com/nv49tYWc

Думки

  • Наскільки я бачу, вирівнювання не є причиною. Навіть якщо розмір сторінки палиці становить 16 Кбіт, запуск корисного навантаження криптовалюти в будь-якому разі вирівняється до 2 Мбіт.
  • --allow-discards (для luxOpen cryptsetup) не допомогло, як я очікував.
  • Роблячи набагато менше експериментів з цим, я спостерігав дуже схожу поведінку із зовнішнім жорстким диском, підключеним через адаптер USB3.0.
  • Мені здається, що система записує блоки 64KiB. Systemtrap сценарій я спробував показує , що принаймні. /sys/block/sdf/statпідтримує цю гіпотезу, оскільки багато записів об'єднано. Тому я здогадуюсь, що написання занадто маленькими блоками не є причиною.
  • Не пощастило змінити планувальник блоків черг пристроїв на NOOP.
  • Введення крипти в об'єм LVM не допомогло.

Очищення кеш-диска перед кожним тестом усуне це як можливу причину швидкості (648 Мб / с звучить недосяжно в даний час, поза межами оперативної пам'яті)
Xen2050

Відповіді:


18

Відповідь (як я тепер знаю): паралельність .

Коротше кажучи : моє послідовне записування , використовуючи ddабо коли копіює файл (наприклад, у щоденному використанні), стає псевдовипадковою записом (погано), оскільки чотири потоки працюють одночасно над записом зашифрованих даних на блоковий пристрій після одночасного використання шифрування (добре).

Пом'якшення (для "старих" ядер)

Негативний ефект можна пом'якшити, збільшивши кількість запитів у черзі в черзі планувальників вводу-виводу таким чином:

echo 4096 | sudo tee /sys/block/sdc/queue/nr_requests

У моєму випадку це майже втричі (~ 56 Мб / с) пропускну здатність для тестування випадкових даних 4 Гб, пояснено в моєму запитанні. Звичайно, продуктивність як і раніше не вистачає 100 Мб / с порівняно з незашифрованим IO.

Розслідування

Багатоядерний blktrace

Далі я дослідив проблемний сценарій, коли btrfs розміщується на вершині блокового пристрою, зашифрованого LUKS. Щоб показати мені, які інструкції щодо запису видаються фактичному блоковому пристрою, я використав blktraceце так:

sudo blktrace -a write -d /dev/sdc -o - | blkparse -b 1 -i - | grep -w D

Це робить (наскільки мені вдалося зрозуміти) прослідкувати запит вводу-виводу, /dev/sdcякий є типом " написати ", а потім проаналізувати це на читаному людиною висновку, але додатково обмежити вихід на дію " D ", що є (згідно man blkparse) " IO видається водієві ".

Результат був приблизно таким (див. Приблизно 5000 рядків виходу багатоядерного журналу ):

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]
  • Колонка 1: основний, другорядний блок пристрою
  • Стовпець 2: ідентифікатор процесора
  • Колонка 3: порядковий номер
  • Колонка 4: штамп часу
  • Стовпець 5: ідентифікатор процесу
  • Колонка 6: дія
  • Колонка 7: Дані RWBS (тип, сектор, довжина)

Це фрагмент виводу, отриманого під ddчас передачі випадкових даних 4 Гб на змонтовану файлову систему. Зрозуміло, що задіяні принаймні два процеси. Решта журналу показує, що над ним фактично працюють усі чотири процесори. На жаль, запити на запит більше не замовляються. У той час як CPU0 пише десь близько 38038416-го сектору, CPU1, який планується згодом, записує десь у секторі 35713872. Це погано.

Одиночний blktrace

Я зробив той же експеримент після відключення багатопотокової передачі та відключення другого ядра мого процесора. Звичайно, тільки один процесор бере участь у написанні на флешку. Але що ще важливіше, запит на запис є належним чином послідовним, через що повна продуктивність запису ~ 170 Мб / с досягається в іншому випадку.

Подивіться приблизно на 5000 рядків виведення в одиночному журналі .

Обговорення

Тепер, коли я знаю причину та належні пошукові терміни Google, інформація про цю проблему кипить на поверхню. Як виявляється, я не перший, хто помітив.

Виправлено в поточних ядрах (> = 4.0.2)

Оскільки я (пізніше) виявив, що ядро виконує явну ціль цієї проблеми, я хотів спробувати оновлене ядро. [Після того як скомпілював його, а потім з’ясував, що це вже є debian/sid] Виявляється, проблема справді виправлена. Я не знаю точного випуску ядра, в якому з'явилося виправлення, але оригінальний фіксатор дасть підказки для всіх, хто цікавиться.

Для запису:

$ 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

Наконечник капелюха до Мікуласа Паточки, який є автором комітету.


1
Я використовую btrfs на luks з ядром 4.12.12, і уповільнення все ще є!
brauliobo

чому ти кажеш, що уповільнення все ще є? яку посилання ви використовуєте, щоб у вас не виникло сповільнення? яка ваша установка? Ви перевіряли працездатність диска, лише видаляючи LUKS?
schlimmchen

підтвердив, що це все ще пов’язано з LUKS unix.stackexchange.com/a/393521/39985
brauliobo

1
Тепер я розумію, чому ви б писали про те, що все ще відчуваєте «уповільнення». Однак ваша проблема пов'язана лише з цією проблемою, це точно не та сама проблема (відставання від низької продуктивності). Я також переживаю ці набридливі гикавки, тому я дуже вдячний, що ви вказали на свою проблему тут! Не використовувати LUKS - це не варіант, але добре знати, що це, здається, пов'язане з причиною.
schlimmchen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.