ZFS: шифрування і стиснення — порядок, що визначає продуктивність

Було корисно?

Ви ввімкнули шифрування, бо безпека попросила чемно (або аудитор — грубо). Потім ввімкнули стиснення,
бо зберігання дороге, і пул завжди «чомусь» заповнений більше, ніж прогнозували. А тепер продуктивність дивна:
стрибки CPU, флуктуації затримок, і «чому цей датасет повільніший за нешифрований?» стало щотижневою ритуальною темою.

ZFS детермінований. Ваше навантаження — ні. Різниця між ними — те місце, де живе біль у продакшені. Закриємо цю різницю:
який порядок обробки даних у конвеєрі, які ручки важливі і як довести, що саме вас обмежує.

Порядок конвеєра: що відбувається першим, і чому вам це має бути важливо

ZFS не «трохи» стискає і не «ніби» шифрує. Воно виконує обидві операції в дуже конкретному конвеєрі, і наслідки продуктивності
слідують за цим порядком, як тінь.

Що ZFS робить з вашими даними (спрощена, але точна модель)

Для нативного шифрування ZFS (функція на рівні датасету) важлива послідовність така:

  1. Додаток записує логічні блоки (файли, сторінки БД, блоки VM) у світ recordsize/volblocksize датасету.
  2. Спочатку відбувається стиснення (якщо ввімкнено). ZFS пробує стиснути кожен рекорд (наприклад, 128K) незалежно.
    Якщо результат не став меншим достатньо, він може зберегти блок у незжатому вигляді (поведінка залежить від алгоритму, але висновок простий:
    система не буде марнувати простір без прибутку).
  3. Після стиснення відбувається шифрування. Це ключовий момент. Шифрування випадкоподібного шифртексту фактично робить його
    нестисненним, тож якби ви зашифрували спочатку, то стиснення стало б марним.
  4. Обчислюються контрольні суми для цілісності, і ZFS записує блоки у розмітку vdev пулу з семантикою copy-on-write.

Саме порядок (спочатку стиснення, потім шифрування) дозволяє мати одночасно й безпеку, й ефективність по місцю — без магії. Це також пояснює,
чому певні проблеми з продуктивністю з’являються тільки після ввімкнення шифрування: стиснення може й надалі зменшувати I/O, але частина
роботи переходить на CPU. Якщо у вас немає запасу CPU, затримки стануть вашим новим хобі.

Ментальна модель, що дозволяє уникати дурних помилок

Уявляйте так: стиснення зменшує байти; шифрування руйнує візерунки. Тому ви хочете зменшити байти, поки візерунки ще існують. Потім шифруєте.

Якщо ви використовуєте нативне шифрування ZFS, ви отримуєте правильний порядок за дизайном. Якщо ви «шифруєте» на рівні додатку
або зверху над ZFS (шифровані файли в нешифрованому датасеті), ви можете шифрувати до того, як ZFS побачить дані,
і тоді стиснення ZFS буде здебільшого декоративним.

Жарт №1: Вмикати стиснення для вже зашифрованих даних — це як поставити турбіну на велосипед: технічно вражає, функціонально — збиває з пантелику.

Що означає «порядок» у реальному світі

Ця стаття не про філософський порядок; вона про те, куди йдуть CPU-цикли й I/O. Питання, яке вам важливо ставити, таке:

  • Де відбувається шифрування? Нативно в ZFS? На рівні додатку? На файловій системі над ZFS?
  • Де відбувається стиснення? Властивість датасету ZFS? На рівні додатку? У інструменті бекапу?
  • Коли дані стають нестисненними? Зазвичай: після шифрування, після вже стиснених форматів (JPEG, MP4),
    або після стиснення на рівні додатку (наприклад, стиснення сторінок БД).

Факти & історія, що змінюють рішення

Трохи контексту — це інвестиція. Ось конкретні факти та короткі історичні нотатки, які важливі при змінах у продакшн-пулі.

  1. Шифрування ZFS нативне й задається на рівні датасету. Це не окремий шар блочного пристрою, примонтований потім; це властивість датасету з опціями наслідування ключів.
  2. Нативне шифрування з’явилося набагато пізніше за сам ZFS. ZFS створили в середині 2000-х; нативне шифрування додали роками пізніше після довгих дискусій про управління ключами і фіч-флаги.
  3. Стиснення в ZFS існує «вічно» в термінах ZFS, і воно стало дефолтом в багатьох інсталяціях, бо часто покращує продуктивність, зменшуючи I/O.
  4. AES-GCM часто використовується для шифрування ZFS, бо дає автентифіковане шифрування (конфіденційність + цілісність). Та цілісність окрема від, але доповнює, контрольні суми ZFS.
  5. Контрольні суми ZFS — наскрізні: зберігаються і перевіряються при читанні, дозволяючи виявляти тихі пошкодження. Шифрування цього не замінює; воно працює поруч.
  6. Стиснення відбувається на блоках (рекордах) локально. ZFS не стискає «файли»; воно стискає блоки, тому recordsize і форма навантаження мають велике значення.
  7. ARC кешує стиснені дані (а зашифровані датасети мають свої наслідки). Ефективність кешу залежить від післястисненого розміру і шаблонів доступу.
  8. zfs send/receive підтримує режими реплікації зашифрованих даних. Можна послати сирі зашифровані потоки, які не потребують ключів на отримувачі — корисно для недовірених бекап-мет
  9. Сучасні CPU мають апаратне прискорення AES (AES-NI на x86, аналогічне на інших платформах), що перетворює «шифрування повільне» на «шифрування зазвичай нормальне, поки не стане проблемою».

Цитата, бо вона болюча для ops: Gene Kranz сказав: «Failure is not an option.» (Це культурний девіз, не параметр ядра.)

Реалії продуктивності: шифрування, стиснення і реальний CPU, який у вас є

Людям подобаються прості відповіді: «Стиснення швидке», «Шифрування повільне», «NVMe все виправить». Реальність складніша й цікавіша.
Продуктивність — це тристоронні переговори між CPU-циклами, пропускною здатністю пам’яті/поведінкою кешу і затримкою/IOPS накопичувача.

Стиснення може прискорити роботу, навіть якщо воно коштує CPU

Якщо ваш пул обмежений I/O, стиснення часто виграє двічі:

  • Записує менше байт, отже диски роблять менше роботи.
  • Читає менше байт, що може змінити сплески затримок на щось непомітне.

Але стиснення не безкоштовне. Алгоритми як lz4 оптимізовані для швидкості; zstd може обмінювати CPU на кращі коефіцієнти.
Ви обираєте згідно з вузьким місцем. Якщо ви вже CPU-обмежені (висока завантаженість, черга запуску, часті переключення контекстів),
ввімкнення важчого стиснення перетворить незначну проблему на чергу інцидентів.

Накладні витрати шифрування зазвичай «нормальні», поки не стануть проблемою

За наявності апаратного прискорення AES-GCM може бути дуже швидким. Але шифрування додає:

  • CPU-роботу на кожен записаний і прочитаний блок.
  • Трохи додаткової обробки метаданих.
  • Можливий тиск на кеш і пропускну здатність пам’яті при високих потоках.

Режим відмови не завжди очевидний. Ви можете мати багато «середнього CPU», але все одно бракувати голівки на кожне ядро.
Потоки зберігання можуть стати чутливими до затримок; якщо вони працюють на ядрах, вже зайнятих роботою додатків, ви отримаєте флуктуації.

Порядок дає важіль: зменшіть байти до того, як заплатите за шифрування

Оскільки ZFS стискає перед шифруванням, стиснення зменшує обсяг даних, які потрібно зашифрувати і записати.
Це важливо, коли:

  • У вас датасет, який добре стискається (текстові логи, JSON, образи VM із нулями, багато сторінок БД).
  • Ви обмежені пропускною здатністю сховища або мережею реплікації.
  • Ви реплікуєте зашифровані дані (send/receive), де байти у мережі коштують часу.

Якщо дані вже стиснені (медіа, багато бекапів, зашифровані блоби), стиснення не зменшить байти. Ви все одно платите вартість спроби стиснення,
хоча для lz4 вона мала, а для важких рівнів zstd — помітна.

Рівень стиснення — це політика, а не вайб

Спокуса — обрати звучний алгоритм («zstd-19, бо велике число») і назвати це оптимізацією.
Це не інженерія; це костюмована поза.

Практичний підхід:

  • За замовчуванням ставте compression=lz4 майже всюди. Це «безпечний» вибір і часто виграє і по місцю, і по швидкості.
  • Використовуйте compression=zstd (помірний рівень) для датасетів, де ви виміряли реальний профіт і маєте бюджет CPU.
  • Вимикайте стиснення для датасетів, що доведено нестиснені і надзвичайно чутливі до затримок (рідко, але буває).

Управління ключами шифрування може стати вашою проблемою продуктивності

Не напряму — крипто швидке — а через операційні помилки, що викликають затримки й простої. Якщо ключі не завантажені під час завантаження системи, ваші служби
не монтуються, додатки не стартують, і ви будете налагоджувати «продуктивність сховища», яка фактично є «сховище недоступне».

Жарт №2: Найшвидша файлова система — та, що монтується; друга найшвидша — та, що не турбує on-call о 3:00 ранку.

Проєктування датасету: recordsize, volblocksize і відповідність навантаженню

Шифрування і стиснення — не окремі перемикачі. Вони взаємодіють з розмірами блоків і шаблонами доступу. Більшість інцидентів «ZFS повільний»
насправді — «ZFS робить точно те, що ви попросили, і це було дивно».

recordsize: прихований множник

recordsize впливає на файлові датасети (не на zvol) і контролює максимальний розмір блоку, який ZFS використовує для даних файлу.
Більші записи:

  • Покращують послідовну пропускну здатність (менше операцій I/O).
  • Підвищують ефективність стиснення (більше даних на блок, більше шаблонів для стиснення).
  • Можуть погіршити затримки випадкового читання для малих читань (read amplification).

Шифрування і стиснення обидва працюють по рекорду. Якщо ви оберете recordsize, що не відповідає навантаженню, ви посилите
CPU-роботу і I/O у невідповідних місцях.

volblocksize: для zvol — більше шансів, що це «один раз»

Для zvol volblocksize — це розмір блоку, видимий споживачу (VM, iSCSI тощо). Він задається при створенні і
складно змінюється без пересоздання тому.

Якщо ви запускаєте БД або образи VM на zvol, виберіть volblocksize правильно. Якщо гість записує 8K блоки, а ваш volblocksize 128K,
ви виконаєте майстер-клас із write amplification.

Спеціальні vdev і метадані: пастка продуктивності

Шифрування й стиснення стосуються блоків даних, але поведінка метаданих може домінувати над затримками. Якщо ваше навантаження важке з точки зору метаданих
(мільйони малих файлів, контейнери, артефакти збірки), ваш «датасет даних» може виглядати нормально, тоді як метадані трясе.
Спеціальні vdev можуть допомогти, але їх треба проєктувати обережно і захищати як першокласні ресурси.

Практичні завдання: команди, виходи і рішення, які ви приймаєте

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

Завдання 1: Підтвердити властивості шифрування і стиснення на датасеті

cr0x@server:~$ zfs get -o name,property,value,source encryption,keystatus,keylocation,keyformat,compression,compressratio pool/app
NAME      PROPERTY      VALUE           SOURCE
pool/app  encryption    aes-256-gcm      local
pool/app  keystatus     available       -
pool/app  keylocation   prompt          local
pool/app  keyformat     passphrase      local
pool/app  compression   zstd            local
pool/app  compressratio 1.72x           -

Що це означає: шифрування увімкнене, ключ завантажено (keystatus=available), стиснення — zstd, а реальний коефіцієнт 1.72x.

Рішення: Якщо compressratio близький до 1.00x і навантаження чутливе до затримок, розгляньте compression=lz4 або відключення.
Якщо keystatus не available, спочатку виправте завантаження ключа, а не ганяйтеся за «продуктивністю».

Завдання 2: Перевірити, чи ви стискаєте нестиснені дані

cr0x@server:~$ zfs get -o name,property,value compressratio,compression pool/media
NAME        PROPERTY      VALUE  SOURCE
pool/media  compressratio 1.01x  -
pool/media  compression   zstd   local

Що це означає: zstd фактично нічого не робить. Ймовірно, це медіафайли або вже стиснені об’єкти.

Рішення: Переключіть на compression=lz4 або compression=off, якщо CPU гарячий і цей датасет не приносить вигоди.

Завдання 3: Виміряти, чи шифрування присутнє там, де ви думаєте

cr0x@server:~$ zfs get -o name,property,value encryption -r pool
NAME           PROPERTY    VALUE         SOURCE
pool           encryption  off           default
pool/app       encryption  aes-256-gcm    local
pool/app/db    encryption  aes-256-gcm    inherited from pool/app
pool/backups   encryption  off           local

Що це означає: Не все зашифровано. Наслідування працює для pool/app/db; бекапи не зашифровані.

Рішення: Визначте політику: чи повинні бекапи бути зашифрованими? Якщо так, увімкніть шифрування на рівні датасету (або використайте raw sends).

Завдання 4: Перевірити CPU-фічі, що роблять шифрування дешевим (або ні)

cr0x@server:~$ grep -m1 -oE 'aes|sha_ni|pclmulqdq' /proc/cpuinfo | sort -u
aes
pclmulqdq

Що це означає: Є підтримка AES і carry-less multiply; AES-GCM може апаратно прискорюватися.

Рішення: Якщо цього немає на старому обладнанні, очікуйте помітно вищу ціну шифрування в CPU і плануйте ємність відповідно.

Завдання 5: Оглянути навантаження I/O по датасетах і підказки щодо затримок

cr0x@server:~$ zpool iostat -v pool 1 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
pool                         2.10T  5.14T    120    980  18.3M  210M
  mirror-0                   1.05T  2.57T     60    490   9.2M  105M
    nvme0n1                    -      -      30    250   4.6M  52.0M
    nvme1n1                    -      -      30    240   4.6M  53.0M
  mirror-1                   1.05T  2.57T     60    490   9.1M  105M
    nvme2n1                    -      -      30    245   4.5M  52.5M
    nvme3n1                    -      -      30    245   4.6M  52.5M
--------------------------  -----  -----  -----  -----  -----  -----

Що це означає: Інтенсивні записи. Це каже, що пул робить реальну роботу; не хто винен, а куди дивитися далі.

Рішення: Якщо пропускна здатність висока, але затримки погані, досліджуйте синхронні записи, SLOG та насичення CPU, а не гадайте «шифрування повільне».

Завдання 6: Перевірити стан ARC і чи допомагає кешування для стиснених/зашифрованих навантажень

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  size     c
12:10:01   920   180     19    45   25   120   67    15    8  24.1G  31.8G
12:10:02   910   175     19    44   25   116   66    15    9  24.1G  31.8G
12:10:03   950   190     20    50   26   125   66    15    8  24.1G  31.8G

Що це означає: ~80% попадань; ARC корисний. Якщо miss% дуже високий, ви йдете на диски і затримки не забаряться.

Рішення: Якщо промахів багато і робочий набір більший за ARC, налаштуйте пам’ять, розгляньте special vdev/L2ARC (обережно),
або переробіть розклад датасетів. Не звинувачуйте шифрування за кеш-промахи.

Завдання 7: Підтвердити recordsize і чи відповідає він шаблонам доступу

cr0x@server:~$ zfs get -o name,property,value recordsize pool/app
NAME      PROPERTY   VALUE  SOURCE
pool/app  recordsize 128K   local

Що це означає: 128K — поширений дефолт. Чудово для послідовного доступу, не завжди для малих випадкових читань.

Рішення: Для навантажень з великою кількістю малих файлів або інтенсивних випадкових читань розгляньте менший recordsize (наприклад, 16K або 32K) для відповідного датасету.

Завдання 8: Для zvol — перевірити volblocksize (і нічого не шкодувати пізніше)

cr0x@server:~$ zfs get -o name,property,value volblocksize pool/vm-01
NAME       PROPERTY     VALUE  SOURCE
pool/vm-01 volblocksize 16K    local

Що це означає: 16K часто прийнятно для VM-наванттажень; вирівняйте з I/O гостя, коли можливо.

Рішення: Якщо volblocksize дуже великий, а навантаження — малі випадкові записи, плануйте міграцію/пересоздання. Немає героїчного sysctl, що виправить невірне розмірування.

Завдання 9: Перевірити поведінку sync і чи платите ви за надійність, яка не потрібна

cr0x@server:~$ zfs get -o name,property,value sync pool/app/db
NAME        PROPERTY  VALUE  SOURCE
pool/app/db sync      standard  default

Що це означає: ZFS виконує синхронні запити додатка. Бази даних можуть форсувати синхронні записи; затримки це покаже.

Рішення: Тримайте sync=standard для коректності, якщо ви не розумієте ризики. Якщо потрібна низька латентність sync, розгляньте SLOG на NVMe з захистом від втрати живлення.

Завдання 10: Підтвердити стан ключів шифрування після завантаження (надійність операцій)

cr0x@server:~$ zfs get -o name,property,value keystatus -r pool/app
NAME         PROPERTY  VALUE
pool/app     keystatus available
pool/app/db  keystatus available

Що це означає: Ключі завантажені зараз. Це не гарантує, що вони автоматично завантажаться при наступному ребуті.

Рішення: Оберіть стратегію завантаження ключів (prompt vs file vs зовнішній агент), що відповідає вашій автоматизації завантаження і моделі загроз.

Завдання 11: Бенчмарк ефекту стиснення чесно

cr0x@server:~$ zfs create -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=prompt -o compression=lz4 pool/bench-lz4
Enter passphrase:
Re-enter passphrase:
cr0x@server:~$ dd if=/dev/zero of=/pool/bench-lz4/zeros bs=1M count=2048 status=progress
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 2.31 s, 930 MB/s
cr0x@server:~$ zfs get -o name,property,value compressratio used,logicalused pool/bench-lz4
NAME            PROPERTY     VALUE  SOURCE
pool/bench-lz4  compressratio  200.00x  -
pool/bench-lz4  used          12.5M  -
pool/bench-lz4  logicalused   2.00G  -

Що це означає: Нулі дуже добре стискаються; ви бачите «кращий випадок». Також зауважте: шифрування не завадило стисненню, бо стиснення відбулося першим.

Рішення: Виконуйте тести й з реальними даними (сторінки БД, логи, образи VM). Бенчмарки лише з нулями — шлях до красивої брехні.

Завдання 12: Перевірити режим send/receive для зашифрованої реплікації

cr0x@server:~$ zfs send -nvpw pool/app@daily | head
send from @daily estimated size is 58.2G
send from @daily to pool/app@daily incremental size 2.14G

Що це означає: -w вказує на raw send (збережено зашифрований потік). Приймач не потребує дешифрування, щоб зберегти його.

Рішення: Використовуйте raw sends для недовірених бекап-цілей. Якщо приймач має читати дані, використайте звичайні sends і керуйте ключами відповідно.

Завдання 13: Перевірити економію місця по датасетах і чи ви «виграєте»

cr0x@server:~$ zfs list -o name,used,logicalused,compressratio,encryption -r pool/app | head -n 6
NAME          USED  LOGICALUSED  RATIO  ENCRYPTION
pool/app      620G     1.02T     1.69x  aes-256-gcm
pool/app/db   410G      710G     1.73x  aes-256-gcm
pool/app/log   42G      120G     2.85x  aes-256-gcm
pool/app/tmp  168G      170G     1.01x  aes-256-gcm

Що це означає: Логи добре стискаються; tmp — ні. Шифрування послідовне.

Рішення: Розгляньте compression=off (або lz4) для tmp, якщо CPU обмежений, і тримайте сильніше стиснення там, де воно окупається.

Завдання 14: Оглянути стан пулу та scrub (бо проблеми продуктивності люблять хворі пули)

cr0x@server:~$ zpool status -v pool
  pool: pool
 state: ONLINE
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Dec 15 03:30:12 2025
config:

        NAME        STATE     READ WRITE CKSUM
        pool        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            nvme0n1 ONLINE       0     0     0
            nvme1n1 ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            nvme2n1 ONLINE       0     0     0
            nvme3n1 ONLINE       0     0     0

errors: No known data errors

Що це означає: Пул здоровий, останній scrub чистий. Добра відправна точка.

Рішення: Якщо ви бачите помилки або resilvering, припиніть «тонку настройку шифрування/стиснення» і спочатку займіться здоров’ям обладнання/пулу.

Завдання 15: Визначити, чи навантаження — випадкові IOPS чи послідовна пропускна здатність

cr0x@server:~$ iostat -x 1 3
avg-cpu:  %user %nice %system %iowait  %steal   %idle
          35.2   0.0     9.8     1.2     0.0    53.8

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
nvme0n1          30.0   250.0  4700.0 52000.0   1.5    0.4   11.2
nvme1n1          30.0   240.0  4600.0 53000.0   1.6    0.4   11.0

Що це означає: Низький iowait і низьке завантаження пристроїв вказують, що сховище не насичене. CPU виконує реальну роботу.

Рішення: Якщо повільно, але диски не зайняті, підозрівайте CPU (рівень стиснення, накладні витрати шифрування, контрольні суми) або поведінку додатку (синхронні записи).

Швидкий план діагностики: знайти вузьке місце за хвилини

Коли продуктивність падає після ввімкнення шифрування або зміни стиснення, не займайтеся «крутінням трьома ручками і надією».
Робіть це в порядку. Зупиніться, коли знайдете обмеження.

Перше: чи пул здоровий і не виконує відновлення?

  • Запустіть zpool status. Подивіться на resilvering, scrub, помилки контрольних сум.
  • Якщо іде resilver або scrub, прийміть знижене виконання або перенесіть роботи. Налаштування не виправить фізику.

Друге: чи ви I/O-обмежені або CPU-обмежені?

  • Запустіть zpool iostat -v 1 і iostat -x 1.
  • Якщо пристрої мають високий %util і await росте: I/O-обмеження.
  • Якщо пристрої холодні, а CPU гарячий: CPU-обмеження (часто стиснення/шифрування/контрольні суми або накладні додатків).

Третє: чи винен latency синхронних записів?

  • Перевірте властивість датасету sync.
  • Перевірте, чи навантаження — база даних або VM з fsync-важкими патернами.
  • Якщо домінують sync-запити і у вас немає належного SLOG, продуктивність буде «нормальною», поки раптом не перестане бути.

Четверте: чи ваші дані стискаються? Чи ви просто спалюєте CPU?

  • Перевірте compressratio і співвідношення logicalused vs used.
  • Якщо коефіцієнт ~1.00x на гарячих датасетах і CPU напружений, оберіть lz4 або вимкніть стиснення в цих датасетах.

П’яте: чи невірне розмірування блоків?

  • Перевірте recordsize для файлових датасетів.
  • Перевірте volblocksize для zvol.
  • Невідповідність викликає ампліфікацію, яка виглядає як «накладні витрати шифрування», бо все сповільнюється одночасно.

Три корпоративні міні-історії з передової

1) Інцидент через хибне припущення: «Шифрування зламало стиснення»

Середня SaaS-компанія розгорнула нативне шифрування ZFS, щоби задовольнити анкету клієнта. Інженер, що робив зміну,
увімкнув шифрування на нових датасетах і залишив стиснення як є (zstd). За тиждень фінанси помітили уповільнення росту використання простору.
Усі заспокоїлися. Потім почалися скарги на затримки: API таймаути, фонова робота відстає, і на каналі інцидентів з’явилася нарація «ZFS тепер повільний».

Хибне припущення було тонке: команда вірила, що шифрування не дозволить стисненню і отже збільшить I/O. В їхній уяві
сховище стане більш завантаженим, тож вони зосередилися на пулі: розгортка vdev, глибина черги, «можливо треба більше NVMe». Тим часом графіки пулу були нудні — низьке завантаження, без явного насичення.

Фікс знайшов той, хто поставив немодний запит: «Чи CPU робить щось інакше?» Вони перевірили compressratio і побачили, що стиснення ще ефективне.
Також помітили, що ноди додатків стали CPU-щільними через окреме розгортання TLS-термінації на тих же хостах, що і сервіси зберігання. Зміна шифрування була соломинкою, не вантажівкою.

Вони перемістили сервіси зберігання на хости з більшим per-core запасом та змінили стиснення з zstd на lz4 для найбільш навантаженого випадкового запису. Затримки стабілізувалися.
Післямова була відверта: шифрування не вбило стиснення; некоректне планування ємності вбило планування ємності.

2) Оптимізація, що відкотилася: «zstd-19 скрізь»

Команда Enterprise IT мігрувала з масиву на ZFS і полюбила економію місця від стиснення. Хтось прочитав про великі коефіцієнти zstd та вирішив стандартизувати високий рівень по всіх датасетах, включно з VM storage і зайнятим build-cache.

Початкові результати тішили: коефіцієнт стиснення покращився, графіки росту простору робили всіх розумними. Потім helpdesk почав отримувати скарги «VM гальмує» — їх важко було відтворити.
Build-farm почав пропускати SLA на невеликі величини — достатньо, щоб дратувати команди без великого інциденту.

Повернення відбулося типово: вони покращили ефективність простору за рахунок CPU-латентності на кожне I/O. Високі рівні стиснення збільшують CPU-час на блок.
На послідовних навантаженнях це можна приховати пропускною здатністю. На випадковому I/O — ні. Кожен I/O отримав невеликий CPU-податок, і сума маленьких податків створила системну флуктуацію.

Вони повернули VM-датасети на lz4, залишили помірний zstd для архівів логів і засвоїли правило: стиснення — це властивість навантаження, а не загальна догма.

3) Нудна, але правильна практика, що врятувала день: завантаження ключів і дисципліна реплікації

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

Один нод сховища вийшов із ладу — апаратна причина, без романтики. Вони промоутнули репліку, імпортували пул і підняли сервіси.
Відновлення не було швидким, але було передбачуваним. І головне — це не перетворилося на хаос з ключами.

Деталь, що врятувала: вони використовували raw sends для офсайтних копій і забезпечили, щоб сайт відновлення мав необхідні ключі (і процес їхнього завантаження) задокументованими і відрепетированими.
Приймачеві не потрібно було дешифрувати raw-потік, щоб зберегти його, що зменшило «руків» у критичний момент.

Постмортем не мав феєрверків. Було майже розчарування. Ось як виглядає успіх у продакшені: буденні відновлення і відсутність пізнього криптографічного імпровізації.

Типові помилки: симптом → корінь проблеми → виправлення

Це повторювані шаблони. Якщо ви бачите симптом — не сперечайтеся в Slack. Ідіть прямо до кореня і виправляйте.

1) Симптом: коефіцієнт стиснення ~1.00x, CPU підвищений

Корінь проблеми: Дані вже стиснені або зашифровані до того, як ZFS їх побачив (медіа, зашифровані бекапи, шифрування на рівні додатку).

Виправлення: Використайте compression=lz4 або compression=off для такого датасету. Тримайте стиснення там, де воно дійсно окупається.

2) Симптом: продуктивність впала після ввімкнення шифрування, але диски не зайняті

Корінь проблеми: CPU-обмеження: шифрування + стиснення + контрольні суми тепер конкурують з роботою додатків.

Виправлення: Зменшіть рівень стиснення (zstd → lz4), додайте запас CPU, ізолюйте сервіси зберігання або масштабуйтеся горизонтально. Підтвердіть висновки через iostat і ARC-статистику.

3) Симптом: сплески затримок на записах БД, особливо в піку

Корінь проблеми: синхронні записи (fsync) змушують ZIL поводитися; немає швидкого SLOG з захистом від втрати живлення, або SLOG неправильно розмірований/працює некоректно.

Виправлення: Тримайте sync=standard; додайте правильний SLOG-пристрій; валідируйте з навантаженнями. Не ставте sync=disabled як «фікс продуктивності», якщо вам не подобається пояснювати втрату даних.

4) Симптом: сховище VM відчувається «випадково повільним», малі I/O жахливі

Корінь проблеми: Неправильний volblocksize викликає write amplification; іноді в поєднанні з високими рівнями стиснення.

Виправлення: Пересоздайте zvol з правильним volblocksize (часто 8K/16K залежно від навантаження) і мігруйте дані; використовуйте lz4 для VM zvol, якщо немає виміряного протилежного доказу.

5) Симптом: система завантажилася, але датасети не монтуються; служби «таємничо» падають

Корінь проблеми: Зашифровані датасети з ключами, які не завантажуються при завантаженні; keylocation=prompt на безголових системах; відсутня автоматизація.

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

6) Симптом: реплікація повільна, CPU на відправнику або приймачі стрибає

Корінь проблеми: Нерaw sends вимагають дешифрування/перешифрування або рекомпресії; також сильне стиснення на живих датасетах додає CPU-навантаження під час send.

Виправлення: Використовуйте raw sends для зашифрованих бекапів, коли приймачу не потрібен plaintext. Розгляньте налаштування рівня стиснення для датасетів з агресивними темпами змін.

Чеклісти / покроковий план

Чекліст A: Налаштування зашифрованого + стисненого датасету (продакшн-безпечні дефолти)

  1. Створіть окремий датасет для кожного класу навантаження (db, логи, медіа, vm, бекапи).
  2. Увімкніть шифрування під час створення датасету (сплануйте наслідування ключів навмисно).
  3. Почніть з compression=lz4, якщо немає виміреної причини для zstd.
  4. Встановіть recordsize відповідно до навантаження (великий для послідовного; менший для випадкових читань).
  5. Для zvol обирайте volblocksize уважно (задокументуйте його).
  6. Визначте політику sync і чи потрібен вам SLOG.
  7. Тест перезавантаження: чи може система імпортувати пул і завантажувати ключі передбачувано?

Чекліст B: Зміна стиснення на існуючому датасеті без драми

  1. Зміряйте початковий стан: затримки, CPU, compressratio і zpool iostat під репрезентативним навантаженням.
  2. Змініть властивість стиснення (застосовується до нових записів; старі блоки залишаться як є).
  3. Спостерігайте під реальним навантаженням; не довіряйте лише мікробенчмаркам.
  4. Якщо потрібно перезаписати існуючі дані, плануйте rewrite (send/receive у новий датасет або копію/rsync).
  5. Оцінюйте через тиждень типової роботи; короткі тести пропускають реальну світову ентропію.

Чекліст C: Операційна гігієна шифрування (щоб уникнути «не монтується»)

  1. Стандартизуйте keyformat і keylocation у середовищах, де це можливо.
  2. Документуйте кроки завантаження ключів і хто має доступ.
  3. Тестуйте відновлення: імпорт пулу, завантаження ключів, монтування датасетів, запуск сервісів.
  4. Перевірте режим реплікації (raw vs non-raw) щодо цілей безпеки.
  5. Аудитуйте наслідування: переконайтеся, що чутливі дочірні датасети випадково не залишилися нешифрованими.

FAQ

1) Чи шифрує ZFS перед тим, як стискати?

Для нативного шифрування ZFS спочатку стискає, потім шифрує. Саме тому стиснення все ще працює на зашифрованих датасетах.

2) Чому стиснення неефективне на деяких зашифрованих датасетах?

Зазвичай тому, що дані були вже зашифровані або стиснені до того, як ZFS їх побачив (шифрування на рівні додатку, медіа-формати,
стиснені бекапи). ZFS не може стиснути випадковість.

3) Що обрати з-поміж zstd чи lz4 для зашифрованих датасетів?

За замовчуванням — lz4 для гарячих, чутливих до затримок датасетів. Використовуйте zstd, коли ви виміряли значну економію місця і маєте бюджет CPU.
Шифрування не міняє цього правила; воно просто додає ще одного споживача CPU.

4) Якщо я змінюю стиснення, чи ZFS перекомпримує існуючі дані?

Ні. Властивість впливає на нові записи. Щоб перекомпресувати існуючі дані, потрібно їх перезаписати (copy або send/receive у новий датасет).

5) Чи шифрування шкодить кешуванню ARC?

Шифрування змінює те, що ZFS має робити при читанні/записі, але ефективність ARC здебільшого залежить від шаблонів доступу і розміру робочого набору.
Якщо у вас багато промахів ARC, ви відчуєте це незалежно від шифрування.

6) Чи raw send — правильний вибір для зашифрованих бекапів?

Якщо ціль бекапу не повинна мати доступ до plaintext, raw send — відмінний вибір: він зберігає шифрування і уникає експозиції ключів на приймачі.
Якщо вам потрібні відновлення, які монтуються й читаються на приймачі, плануйте управління ключами відповідно.

7) Чи можу я увімкнути шифрування на вже існуючому нешифрованому датасеті?

Не «на місці» в тому сенсі, як люди сподіваються. Практично ви створюєте новий зашифрований датасет і мігруєте дані (send/receive або copy),
потім переключаєтеся.

8) Яка найбільша ручка продуктивності крім алгоритму стиснення?

Розмір блоків: recordsize для файлових датасетів і volblocksize для zvol. Неправильне розмірування створює ампліфікацію, від якої жоден алгоритм не врятує.

9) Чи варто ставити sync=disabled, щоб прискорити зашифровані датасети?

Ні, не як загальне рішення. Це міняє надійність на швидкість і перетворює деякі відмови в втрату даних. Якщо синхронна латентність — проблема,
вирішіть її через правильний SLOG або налаштування додатку.

10) Як зрозуміти, чи накладні витрати шифрування — моє вузьке місце?

Якщо диски не насичені, ARC не проблема, і CPU завантажений під час інтенсивних I/O операцій, шифрування (разом зі стисненням/контрольними сумами)
може бути частиною проблеми. Підтвердіть через метрики CPU і порівняння поведінки з lz4 проти важчих рівнів стиснення.

Висновок: практичні наступні кроки

«Порядок, що визначає продуктивність», простий: зменшуйте байти, поки вони ще стискувані, потім шифруйте. Нативне шифрування ZFS
вже це робить. Ваше завдання — не боротися з цим порядком; ваше завдання — переконатися, що решта системи — запас CPU, розмір блоків,
політика sync і операції з ключами — не саботують вигоду.

Наступні кроки, які ви можете виконати цього тижня

  1. Проінвентаризуйте датасети: шифрування вкл/вимк, алгоритм стиснення, compressratio, recordsize/volblocksize.
  2. Визначте гарячі датасети з compressratio ~1.00x і вирішіть, чи стиснення повинно бути lz4 або вимкнене.
  3. Одного разу під час піку пройдіть швидкий план діагностики, зафіксуйте результати і збережіть їх як базу.
  4. Виберіть один клас навантаження (VM або бази даних) і перевірте розмір блоків; сплануйте міграції для найгірших.
  5. Протестуйте перезавантаження + завантаження ключів + запуск сервісів у контрольованому вікні. Якщо це не нудно, то не готово.
← Попередня
ZFS dedup: Прапорець, який їсть ОЗП і руйнує вихідні
Наступна →
Знімок Proxmox завис: безпечне очищення залишків LVM-thin

Залишити коментар