Реплікація по WAN — це той момент, коли ZFS перестає бути просто акуратною функцією файлової системи й перетворюється на іспит з операційної витривалості. Локально zfs send | zfs recv відчувається як конвеєр. По лінку з затримкою 50–200 мс, втратою пакетів і «допоміжними» середніми пристроями це стає пінболом: пропускна здатність падає, CPU на максимумі, SSH пригальмовує, і ваш RPO починає домовлятися з реальністю.
Це польовий посібник, як зробити ZFS send швидким на повільних каналах без перетворення платформи зберігання на науковий стенд. Написано для людей, які щодня переміщають байти: SRE, інженерів зберігання й нещасних чергових, що успадкували «прості реплікації», які працюють тільки коли ніхто не дивиться.
1. Ментальна модель реплікації по WAN
Продуктивність реплікації ZFS — це не один регулятор. Це конвеєр із взаємопов’язаними обмеженнями: I/O диска на відправнику, CPU для стиснення/шифрування, пам’ять і буферизація, поведінка TCP при затримці, накладні витрати SSH та поведінка запису на приймачі. Якщо налаштовувати лише один компонент, ви часто просто перемістите «пляшкове горло» в інше місце — а іноді зробите його менш помітним.
Найпростіший спосіб зберегти здоровий глузд — ставитися до реплікації як до сервісу з SLO:
- RPO: скільки даних ви можете дозволити собі втратити (впливає на частоту снапшотів і розмір send).
- RTO: як швидко ви можете відновити дані (впливає на збереження, тестування й на те, чи мають бути властивості
zfs receiveкоректні). - Бюджет: пропускна здатність, запас CPU і наскільки складною може бути операційна робота о 3-й ранку.
Потім визначте конвеєр у голові:
- Вибір снапшота: що змінилося з останнього разу?
- Send: ZFS читає блоки й генерує стрім.
- Трансформація: опційне стиснення, опційне шифрування (рідне ZFS або SSH).
- Транспорт: TCP через шлях із великою затримкою.
- Receive: ZFS записує блоки, оновлює метадані, комітить TXG.
У LAN домінують диск і CPU. У WAN затримка та втрата пакетів підсилюють кожну незначну неефективність. Лінк із RTT 100 мс — це не просто «трохи повільніше за локальний» — він змінює, як TCP нарощує вікно, як швидко витрачаються буфери і як болісний може бути одиночний повторний передача.
Перший жарт (обов’язково, і заслужено): реплікація по WAN — це як переїжджати на самокаті — технічно можливо, але кожна відсутня мотузка стає життєвим вибором.
2. Цікавинки та історичний контекст
Шість–десять конкретних пунктів контексту, які важливі на практиці:
- ZFS send/receive старіше за багато «cloud-native» продуктів для бекапу. Оригінальний дизайн OpenSolaris ZFS враховував реплікацію снапшотів як базову операцію, а не як доповнення.
- Інкрементальні send’и працюють на рівні блоків, а не файлів. Ось чому вони можуть бути надзвичайно ефективні — але також чому певні навантаження (зображення віртуальних машин із великим чурном) можуть давати несподівано великі дельти.
- Пропускна здатність TCP обмежена BDP. Якщо буфери сокета менші за bandwidth-delay product, ви втрачаєте доступну пропускну здатність навіть коли все інше ідеально.
- За замовчуванням SSH консервативний для інтерактиву. Воно не створене для багатогодинних масових передач, особливо через високу затримку.
- OpenZFS додав підтримку resumable send, щоб перервану реплікацію можна було продовжити без початку з нуля — одна з найкорисніших опцій для операційників.
- Стиснення то приходить в моду, то виходить. На сучасних CPU легке стиснення (LZ4) часто «майже безкоштовне» і може бути різницею між насиченням лінку і повзанням.
- Рішення щодо recordsize та volblocksize впливають на реплікацію. Великі послідовні блоки реплікуються ефективно; дрібні випадкові блоки збільшують метадані й накладні витрати — це особливо помітно в WAN.
- Реплікація чутлива до поведінки запису на приймачі. Пул приймача зі стесненим SLOG, невідповідністю ashift або великим sync-навантаженням може гальмувати весь конвеєр.
3. Базова оцінка: що означає «повільно»
Перш ніж налаштовувати ZFS, з’ясуйте, на що ваш лінк реально здатний. Люди регулярно заявляють «у нас є 1 Gbps канал», а потім реплікують зі швидкістю 30–80 Mbps і звинувачують ZFS. Половина часу канал реальний; корисна пропускна спроможність — ні, тому що QoS, VPN-накладні витрати, втрата пакетів або неправильна конфігурація BDP тихо під’їдають ваш результат.
Що потрібно знати:
- RTT: 20 мс — це інша планета порівняно з 120 мс.
- Втрата: 0.1% втрата може розвалити TCP-пропускну здатність на деяких шляхах.
- MTU/MSS: фрагментація і чорні діри — тихі вбивці.
- BDP: bandwidth × RTT; порівняйте із розмірами сокет-буферів.
Тільки після розуміння мережі інтерпретуйте числа реплікації. Інакше ви налаштовуєте файлову систему, щоб компенсувати фаєрвол, який вважає великі пакети моральним провалом.
4. Конвеєр реплікації: де швидкість гине
4.1 Стратегія снапшотів: менше, розумніші дельти
На WAN-каналах реплікація — це гра консистентності й розміру дельти. Багато дрібних снапшотів зменшують максимальний розмір дельти й ризик «одного великого send», що заб’є канал — але занадто багато снапшотів збільшують метаданні й операційну складність.
Операційно виграшна модель:
- Часті снапшоти для короткого RPO (наприклад, 5–15 хв) для критичних датасетів.
- Рідші снапшоти для об’ємних/низьковартісних датасетів.
- Зберігайте принаймні одну відому добру базову версію для кожного цільового реплікаційного місця.
4.2 Відправник: шаблон читання, CPU та прапори zfs send
zfs send може бути настільки швидким, що наситить NVMe локально, і все ще бути «неправильного формату» для WAN. Великі важелі:
- Інкрементальні send’и:
-iабо-I, плюс розумні імена снапшотів. - Raw send:
-wзберігає блоки зашифрованими/стиснутими як зберігаються (коли увімкнене шифрування на датасеті) й уникає повторної обробки; часто великий виграш по CPU. - Великі блоки: реплікація виграє від більших послідовних читань; якщо навантаження по суті випадкове, важливіше буферування.
- Включати властивості:
-pабо-Rвпливають на коректність, а не тільки на швидкість — помилки тут створюють «швидкі» реплікації, які не відновлюються правильно.
4.3 Трансформація: вибір стиснення та шифрування
На повільних каналах стиснення часто приносить більше користі, ніж коштує — поки не перевищить CPU. Обмеження — запас CPU на обох кінцях. LZ4 — типовий «ймовірно безпечний» вибір; важке стиснення може стати вузьким горлом по CPU, а подвійне стиснення витрачає цикли даремно.
Шифрування: ви будете шифрувати по WAN. Єдине питання — де. Якщо ви вже використовуєте нативне шифрування ZFS, zfs send -w (raw) дозволяє уникнути операцій decrypt/re-encrypt. Якщо покладаєтесь на SSH для шифрування, налаштуйте SSH під масові передачі та розгляньте швидкі шифри, які добре працюють на вашому обладнанні.
4.4 Транспорт: затримка, буфери і чому ваша пропускна здатність зависає
TCP потребує даних «в польоті», щоб тримати трубу повною. На каналі 200 Mbps із RTT 100 мс BDP ≈ 2.5 MB (200 мегабіт/с ≈ 25 MB/с; × 0.1 с ≈ 2.5 MB). Якщо сокет-буфери відправника/приймача менші за це, ви фізично не зможете досягти лінійної швидкості.
Додайте втрати. TCP трактує втрату як затори, зменшує вікно й повільно нарощує його назад. Через великі RTT нарощування повільне. Ось чому лінк, який «почувається нормальним» для веб-трафіку, може бути жахливим для тривалої реплікації.
4.5 Приймач: записи, TXG і загадка «приймач повільніший за відправника»
Продуктивність на приймачі часто приховане вузьке горло. Типові підозрювані:
- Суперечність у пулі: інші навантаження створюють випадкові записи та тиск на sync.
- Поведінка sync: датасети з
sync=alwaysабо перевантажений SLOG можуть гальмувати коміти. - Малий recordsize: приймачу потрібно виконати більше роботи з метаданими для тієї ж кількості користувацьких даних.
- Очікування несумісності ashift: не налаштування реплікації, але фактор дизайну пулу, що впливає на write amplification.
5. Практичні завдання (команди + інтерпретація)
Це реальні завдання, які ви можете виконати на типових системах OpenZFS-on-Linux. Налаштуйте імена датасетів і інтерфейси. Кожне завдання містить, на що дивитися, тому що просто «запустити команду» — це не операція.
Завдання 1: Підтвердити інвентар датасетів і снапшотів
cr0x@sender:~$ zfs list -t filesystem,volume -o name,used,avail,refer,mountpoint
cr0x@sender:~$ zfs list -t snapshot -o name,creation,used -s creation | tail -n 20
Інтерпретація: Ви перевіряєте, що збираєтеся реплікувати і чи існує ланцюг снапшотів. Якщо снапшоти відсутні або нерегулярні, інкрементальні send’и зазнають невдачі або змушуватимуть робити дорогі повні send’и.
Завдання 2: Оцінити розмір дельти між снапшотами
cr0x@sender:~$ zfs list -t snapshot -o name,used,refer -s creation tank/app
cr0x@sender:~$ zfs send -nPv -i tank/app@snaphourly-001 tank/app@snaphourly-002
total estimated size is 38.2G
send from @snaphourly-001 to tank/app@snaphourly-002 estimated size is 38.2G
Інтерпретація: Якщо «годинна» дельта 38 GB, у вас не проблема реплікації — у вас невідповідність навантаження або кроку снапшотів. Цей вивід — перевірка реальності вашого RPO.
Завдання 3: Виміряти сирий throughput send локально (прибрати WAN)
cr0x@sender:~$ zfs send -Pv tank/app@snaphourly-002 | pv > /dev/null
12.5GiB 0:00:18 [ 702MiB/s] [ <=> ]
Інтерпретація: Якщо локальний send швидкий, I/O відправника й сам zfs send не є вашим вузьким горлом. Якщо це повільно, виправте пул відправника, тиск ARC або структуру снапшотів перш ніж звинувачувати мережу.
Завдання 4: Виміряти сирий throughput receive локально
cr0x@receiver:~$ zfs create -o mountpoint=none tank/replica-test
cr0x@sender:~$ zfs send -Pv tank/app@snaphourly-002 | ssh receiver 'pv | sudo zfs recv -u tank/replica-test/app'
Інтерпретація: Це тестує наскрізний шлях, але все ще не ваш WAN. Якщо receive тут повільний, ваш пул приймача — підозрюваний (або CPU для декомпресії/шифрування).
Завдання 5: Підтвердити TCP RTT, сигнали втрат і маршрути
cr0x@sender:~$ ping -c 20 receiver
cr0x@sender:~$ ip route get receiver
cr0x@sender:~$ ss -ti dst receiver | head -n 40
Інтерпретація: Ping дає грубу RTT. ss -ti показує стан TCP, включно з повторними передачами, congestion window і pacing. Якщо під час реплікації ви бачите зростання retransmits, виправляйте шлях мережі або MTU перед тим, як налаштовувати ZFS.
Завдання 6: Перевірити MTU і виявити типові проблеми PMTUD
cr0x@sender:~$ ip link show dev eth0
cr0x@sender:~$ tracepath receiver | head -n 20
Інтерпретація: Якщо ви на VPN, ефективний MTU часто менший, ніж ви думаєте. tracepath підкаже про зміни PMTU. Незвичності Path MTU часто проявляються як «випадкові зависання» або непослідовна пропускна здатність.
Завдання 7: Перевірити CPU відправника та приймача під час реплікації
cr0x@sender:~$ mpstat -P ALL 1 10
cr0x@sender:~$ pidstat -t 1 -p $(pgrep -n "zfs|ssh|mbuffer|pv" | tr '\n' ',')
Інтерпретація: Якщо один ядро завантажене на максимум (часто крипто SSH або стиснення), ви обмежені CPU. Налаштування WAN не допоможе, якщо конвеєр не може генерувати чи споживати байти достатньо швидко.
Завдання 8: Використати mbuffer, щоб згладити джиттер WAN і тримати трубу повною
cr0x@sender:~$ zfs send -Pv -i tank/app@snapA tank/app@snapB | mbuffer -q -m 1G -s 128k | ssh receiver 'mbuffer -q -m 1G -s 128k | sudo zfs recv -u tank/replica/app'
Інтерпретація: mbuffer розділяє темп відправника і приймача та поглинає джиттер. Якщо це суттєво покращує пропускну здатність, ваше вузьке горло ймовірно в транспорті або в ставах записів приймача, а не в самому zfs send.
Завдання 9: Увімкнути resumable sends і зберегти resume token
cr0x@sender:~$ zfs send -v -s -i tank/app@snapA tank/app@snapB | ssh receiver 'sudo zfs recv -s -u tank/replica/app'
cr0x@receiver:~$ zfs get -H -o value receive_resume_token tank/replica/app
1-ETcK...truncated...GQ
Інтерпретація: Якщо лінк відпаде, ви можете продовжити замість перезапуску. Це обов’язково при ненадійних WAN. Непорожній токен означає, що очікується resumable receive.
Завдання 10: Відновити перервану реплікацію
cr0x@receiver:~$ token=$(zfs get -H -o value receive_resume_token tank/replica/app)
cr0x@sender:~$ zfs send -v -t "$token" | ssh receiver 'sudo zfs recv -s -u tank/replica/app'
Інтерпретація: Якщо resume працює і пропускна здатність повертається, ви довели, що перерва була транспортною або тимчасовою проблемою на віддаленій стороні, а не пошкодженням ланцюга снапшотів.
Завдання 11: Перевірити цілісність реплікації, порівнявши снапшоти
cr0x@receiver:~$ zfs list -t snapshot -o name,creation -s creation tank/replica/app | tail -n 5
cr0x@sender:~$ zfs list -t snapshot -o name,creation -s creation tank/app | tail -n 5
Інтерпретація: Імена та порядок снапшотів мають відповідати вашому запланованому набору реплікації. Якщо ні, ви можете мовчки не реплікувати те, що вважаєте.
Завдання 12: Підтвердити, які властивості отримуються і чи повинні вони бути локальними
cr0x@receiver:~$ zfs get -o name,property,value,source compression,encryption,keylocation,atime,recordsize tank/replica/app
Інтерпретація: Властивості впливають на продуктивність і поведінку відновлення. Наприклад, примусове atime=on на репліці, що використовується для тестування DR, може створити фоновий шум записів у найгірший момент.
Завдання 13: Дізнатися, чи заблокований приймач на sync або під тиском TXG
cr0x@receiver:~$ zpool iostat -v 1 10
cr0x@receiver:~$ cat /proc/spl/kstat/zfs/arcstats | head -n 5
cr0x@receiver:~$ cat /proc/spl/kstat/zfs/txgs | head -n 50
Інтерпретація: zpool iostat показує, чи пул насичений і чи відстає якийсь vdev. Статистика TXG може підказати затримки комітів. Якщо пул є вузьким горлом, можна вічно оптимізувати мережу і все одно повзти.
Завдання 14: Налаштувати SSH для масової передачі (обережно) і спостерігати вплив на CPU
cr0x@sender:~$ zfs send -Pv -i tank/app@snapA tank/app@snapB | \
ssh -T -o Compression=no -o IPQoS=throughput receiver 'pv | sudo zfs recv -u tank/replica/app'
Інтерпретація: Вимкнення стиснення SSH уникає подвійного стиснення вже стиснутих даних. IPQoS=throughput може запобігти ставленню стріму як інтерактивного трафіку в деяких мережах. Завжди вимірюйте CPU і пропускну здатність до і після; «налаштування» може стати дорогим способом відчути продуктивність.
Завдання 15: Перевірити, що приймач випадково не монтує й не індексує
cr0x@receiver:~$ zfs get -o name,property,value mounted,mountpoint canmount tank/replica/app
cr0x@receiver:~$ zfs recv -u tank/replica/app < /dev/null
Інтерпретація: Для DR-реплік часто бажано canmount=off або mountpoint=none і zfs recv -u, щоб уникнути автомонтування, яке запускає сканери, індексатори або «допоміжні» агенти моніторингу, які створюють записи під час реплікації.
6. Швидкий план діагностики
Коли реплікація повільна, не починайте з хаотичної зміни прапорів. Використайте короткий план, який ізолює вузьке горло за хвилини.
Крок 1: Мережа чи хости обмежують?
- Перевірте RTT і повторні передачі під час реплікації.
- Перевірте завантаження CPU на відправнику й приймачі.
- Перевірте zpool iostat на приймачі на предмет тривалого високого використання й затримок.
cr0x@sender:~$ ss -ti dst receiver | sed -n '1,25p'
cr0x@sender:~$ mpstat -P ALL 1 5
cr0x@receiver:~$ zpool iostat -v 1 5
Рішення: Якщо з’являються retransmits і cwnd колапсує, спочатку розглядайте проблему як мережеву. Якщо CPU завантажений — як проблему CPU/крипто/стиснення. Якщо пул приймача на 90–100% із великим часом очікування — як проблему зберігання.
Крок 2: Чи несподівано великий розмір send?
cr0x@sender:~$ zfs send -nPv -i tank/app@last tank/app@now
Рішення: Якщо розмір дельти більший, ніж очікувалося, виправте частоту снапшотів, чурн навантаження або вибір базового снапшота для інкременту (-i vs -I). Налаштування WAN не зменшить дельту.
Крок 3: Чи буферизація стабілізує пропускну здатність?
cr0x@sender:~$ zfs send -Pv -i tank/app@last tank/app@now | mbuffer -m 1G -s 128k | \
ssh receiver 'mbuffer -m 1G -s 128k | sudo zfs recv -u tank/replica/app'
Рішення: Якщо пропускна здатність стає плавнішою й вищою, ви бачили зупинки в конвеєрі (коміти приймача, мережевий джиттер або pacing SSH). Залиште mbuffer і далі дослідіть поведінку запису приймача.
Крок 4: Чи можна надійно відновлювати?
cr0x@receiver:~$ zfs get -H -o value receive_resume_token tank/replica/app
Рішення: Якщо не можете відновити на ненадійних каналах, ви на один транзит від повного пересилання і неприємного вікенду. Виправте можливість resume перед тим, як ганятися за маргінальними пришвидшеннями.
7. Три міні-історії з корпоративного життя
Історія 1: Інцидент через хибне припущення
Конфігурація виглядала розумно на дошці: реплікувати production датасети на DR-сайт щонічно через приватний канал. Команда вважала, що «приватний канал» означає «стабільна пропускна здатність», а «щонічно» — «достатньо». Ніхто не записав RPO; воно існувало як відчуття.
Потім стався продуктовый реліз. Навантаження змінилося зі стабільних записів в БД на багато об’єктів і чурн образів ВМ. Інкрементальні дельти тихо зросли, бо ZFS зробив те, що мав робити: зафіксував зміни і потім відправив їх пізніше. Робота реплікації почала займати більше часу, підповзла за ранок. Люди помічали, але відмахувалися — адже «воно все ще працює».
Під час іншої технічної роботи первинний сайт впав і треба було підняти DR. DR-датасет відставав значно більше, ніж хтось очікував. Вони реплікували «щонічно», але нічний send не завершився. Їхній RPO не був 24 години; він був «коли send випадково закінчиться», що ніяк не годиться в реєстрі ризиків.
Вирішення не було хитрим. Це була нудна інженерія: збільшити частоту снапшотів, додати моніторинг «лаг реплікації в снапшотах/часі», і політику, що реплікація має завершитися в заданому вікні — або спрацює пейджинг. Вони також почали запускати zfs send -nPv оцінки як частину рев’ю змін при великих зрушеннях навантаження.
Історія 2: Оптимізація, що обернулася проти
Інша компанія мала повільний трансконтинентальний лінк і завдання: «зробити реплікацію швидшою». Хтось підвищив стиснення всюди — на датасетах, у пайплайні send і в SSH. На короткому тесті це виглядало чудово: перші хвилини показували більший throughput і менше байт на лінії.
Потім прийшла реальність. CPU на відправнику виріс, але гірше — CPU на приймачі став стрибкоподібним. Пропускна здатність коливалась: сплески прогресу і довгі паузи. Команда сприйняла паузи як «мережеві проблеми» і попросила більший канал. Мережна команда, природно, попросила докази.
Докази з’явилися в mpstat і pidstat: кілька ядер були завантажені стисненням і криптою, а пайплайн запису приймача не встигає. Подвійне стиснення витрачало цикли даремно, бо багато даних (стиснуті бінарні блоби) далі не стискалися. SSH-стиснення додало затримку і витрати CPU без вигоди.
Виправлення було контринтуїтивним: вимкнути стиснення SSH, залишити легке стиснення на датасетах (LZ4) і використати буферизацію для згладжування пауз приймача. Пропускна здатність покращилася, CPU остигнув, і — найкраще — система стала передбачуваною. Головний урок: якщо ви не можете пояснити, куди йдуть CPU-цикли, ви не оптимізуєте — ви граєте в азартну гру з кращими таблицями.
Історія 3: Нудна, але правильна практика, що врятувала становище
Третя організація мала звичку, яка здавалася занадто консервативною: вони наполягали, щоб усі WAN-реплікації були resumable, логувалися й тестувалися щомісяця із симуляцією розриву лінку. Також тримали короткий рукопис у каналі інцидентів: «resume token першим, паніку другим». Це не було гламурно й ніхто за це не отримував підвищення.
Одного кварталу провайдер мав періодичну втрату пакетів кілька днів. Не повний відруб — досить, щоб вивести з рівноваги довгі TCP-потоки і час від часу збивати сесії. Реплікації почали падати посередині. Але тому що роботи використовували resumable sends, вони відновлювались автоматично або однією командою оператора. Ніхто не був змушений перезапускати все з нуля і насичувати лінк на тижні.
В той самий період команда безпеки ввела суворі таймаути фаєрволу, які вбивали «неактивні» SSH-сесії. Пайплайн реплікації зупинявся під тиском TXG на приймачі, здавався «неактивним» для фаєрволу і обривався. Знову: resumable реплікація перетворила кризу на неприємність.
Коли керівництво спитало, чому DR залишався здоровим під час «мережевої нестабільності», чесна відповідь була не «ми ідеально налаштували TCP». Це було «ми припустили, що WAN ненадійний, і спроектувалися під це». В підприємницьких операціях це і є компетентність: вона тиха.
8. Поширені помилки (симптоми + виправлення)
Помилка 1: Розглядати тільки throughput як метрику
Симптом: Ви святкуєте швидкий прогін реплікації, а потім виявляєте, що снапшоти відсутні, властивості не репліковані або відновлення не працює.
Виправлення: Визначте коректність: які датасети, які снапшоти, рекурсивно чи ні, які властивості включені і чи це raw зашифрований реплік. Використовуйте порівняння zfs list -t snapshot і періодичні тести відновлення.
Помилка 2: Повні send’и по WAN через «інкрементальні складні»
Симптом: Реплікація ніколи не закінчується після першого посіву; лінк насичений на дні; RPO постійно дрейфує.
Виправлення: Використовуйте іменування снапшотів і інкрементальні send’и. Якщо потрібно засіяти, зробіть це один раз (ідеально — фізично відправивши диски або використовуючи тимчасовий швидкісний канал), потім запускайте інкременти.
Помилка 3: Подвійне стиснення (датасет + пайплайн + SSH)
Симптом: CPU сплески, коливання throughput і «швидші» налаштування роблять усе повільнішим.
Виправлення: Виберіть одне місце для стиснення. Часто: LZ4 на датасетах, стиснення SSH вимкнено. Вимірюйте за допомогою інструментів CPU.
Помилка 4: Відсутність буферизації при джиттерному WAN
Симптом: Пропускна здатність виглядає як пилкоподібна: сплески та потім паузи; SSH-сесії іноді падають під час тихих фаз.
Виправлення: Додайте буферизацію (mbuffer) на обох кінцях із розумним розподілом пам’яті. Це згладжує короткі паузи приймача й мережевий джиттер.
Помилка 5: Ігнорування стану пулу приймача
Симптом: Відправник локально швидкий, але енд-ту-енд через WAN швидкість погана, навіть якщо лінк не завантажений.
Виправлення: Перевірте zpool iostat -v, латентність і конкуренцію. Реплікація — це інтенсивне на запис навантаження на приймач; ставтеся до цього як до окремого класу навантаження.
Помилка 6: Не використовувати resumable send на ненадійних лінках
Симптом: 6-годинна передача ламається на 5:45 і починається з початку. Мораль падає швидше за throughput.
Виправлення: Використовуйте zfs send -s і zfs recv -s. Захоплюйте і моніторьте resume токени.
Помилка 7: Перекривні задачі реплікації, що конкурують
Симптом: Багато датасетів реплікуються «паралельно», але сумарна пропускна здатність гірша, і чутливі до латентності додатки скаржаться.
Виправлення: Серіалізуйте великі стрими або використовуйте контрольовану конкуренцію. Ваш WAN та пул приймача не стануть швидшими від додаткових потоків; ви лише додасте конкуренцію.
Помилка 8: Вважати, що «WAN в порядку», бо тест швидкості проходить
Симптом: Тести швидкості в браузері проходять, але довгі реплікаційні потоки повзають.
Виправлення: Спостерігайте поведінку TCP (ss -ti), повторні передачі і MTU/PMTUD. Довгі потоки відкривають проблеми маршруту, які короткі тести приховують.
Другий жарт (обов’язково): Якщо ви вважаєте, що втрата пакетів у WAN «майже нульова», у мене є міст на продаж — через VPN, з MTU 9000.
9. Чеклісти / покроковий план
9.1 Покроковий план для нової WAN-реплікації
- Визначте намір: цілі RPO/RTO за класом датасетів (критичні, важливі, best-effort).
- Уніфікуйте імена снапшотів: передбачувані імена, послідовна частота і політика збереження.
- Початковий посів: зробіть одноразовий повний send під час вікна обслуговування або через альтернативний шлях; підтвердіть розмітку на приймачі.
- За замовчуванням зробіть resumable:
zfs send -sіzfs recv -s. - Додайте буферизацію: розгорніть
mbufferз консервативним обсягом пам’яті (наприклад, 512MB–2GB) залежно від RAM хоста. - Виберіть стратегію стиснення: зазвичай LZ4 на датасетах, без стиснення SSH. Якщо використовується нативне шифрування — надавайте перевагу raw send.
- Тротлінг при потребі: уникайте задушування бізнес-трафіку; обмеження швидкості іноді — це функція, а не поступка.
- Перевірте коректність: впевніться, що ланцюги снапшотів, властивості й очікувані датасети прибувають. Тримайте receives відмонтованими, якщо не потрібно.
- Інструментуйте лаг реплікації: вимірюйте «вік останнього реплікованого снапшота» і сповіщайте при перевищенні порогів.
- Тестуйте відновлення: змонтуйте клон репліки або піднімайте тестове середовище за розкладом. Реплікація, з якої ви не відновлювали, — це теорія.
9.2 Операційний чекліст для «реплікація сьогодні повільна»
- Перевірте конкуренцію в пулі приймача:
zpool iostat -v 1 5. - Перевірте повторні передачі TCP/cwnd:
ss -ti dst receiver. - Перевірте прикування CPU:
mpstatіpidstat. - Оцініть розмір дельти:
zfs send -nPv -i. - Спробуйте буферизацію, якщо її ще немає: додайте
mbuffer. - Перевірте статус resume токена; відновіть замість перезапуску.
10. FAQ
Q1: Чи слід використовувати raw send (zfs send -w) по WAN?
Якщо ви використовуєте нативне шифрування ZFS і хочете реплікувати зашифровані датасети без розшифрування, raw send зазвичай правильний вибір. Він також може зменшити навантаження на CPU, бо ZFS передає збережені зашифровані/стиснуті блоки. Операційно це зберігає межі шифрування — саме те, що потрібно для віддалених копій.
Q2: Чи обов’язковий mbuffer?
Не обов’язковий, але це один з інструментів з найвищим ROI для WAN-реплікації, бо згладжує сплески й паузи. Якщо ваш throughput стрибкоподібний або SSH-сесії вмирають під час «тихих» фаз, буферизація — практичне вирішення.
Q3: Чому реплікація зависає в одному і тому ж місці кожного разу?
Часто це тиск на пул приймача або таймаут середнього пристрою в мережі. Перевірте zpool iostat на приймачі на предмет vdev, що досягає 100% використання або має великі waits, і перевірте, чи ваш фаєрвол/NAT має агресивні таймаути, які вбивають довгі сесії.
Q4: Чи запускати кілька send’ів паралельно, щоб краще використовувати лінк?
Іноді так, але обережно. Паралельні потоки допомагають, якщо один потік не може заповнити трубу через обмеження на потік, але вони також збільшують конкуренцію на дисках і CPU і можуть погіршити tail latency для додатків. Спробуйте один добре налаштований потік; якщо він не насичує і хости вільні, тоді тестуйте контрольовану паралельність.
Q5: Яка найкраща частота снапшотів для WAN-реплікації?
Та, що тримає інкрементальні дельти комфортно в межах вашого вікна реплікації з запасом на повторні спроби. Якщо ваш лінк може надійно перемістити X GB/год і навантаження змінює Y GB/год, частота снапшотів має підтримувати дельту менше за те, що ви можете відправити плюс накладні витрати.
Q6: Чи реплікувати рекурсивно з -R?
-R правильний, коли вам потрібна повна ієрархія (діти, снапшоти, властивості) реплікована консистентно. Це також спосіб випадково реплікувати більше, ніж ви мали намір. Використовуйте його, коли це дійсно потрібно, і перевіряйте дерево датасетів на приймачі.
Q7: Як зрозуміти, чи я обмежений CPU через шифрування SSH?
Запустіть реплікацію і спостерігайте mpstat/pidstat. Якщо одне або більше ядер завантажені процесом ssh і ваш лінк недовантажений, SSH-шифрування — головний підозрюваний. Розгляньте raw sends з нативним шифруванням (якщо може бути) або налаштування SSH і здатність CPU хостів.
Q8: Чи безпечно ставити sync=disabled на приймачі, щоб пришвидшити zfs recv?
Це швидко, але ризиковано. Для DR-репліки, де ви можете дозволити собі втратити останні кілька секунд прийнятих даних при аварії, команди іноді свідомо обирають це. Але не робіть цього легковажно: ви змінюєте семантику міцності на приймачі. Якщо робите — документуйте, обмежуйте сферу і тестуйте поведінку при відмові.
Q9: Чому оцінка zfs send -nPv не відповідає фактичному обсягу?
Це оцінка і може варіюватися залежно від шарингу блоків, метаданих і характеристик стріму. Вона все одно корисна для виявлення трендів і рішення «ця дельта божевільна?» — але не для бухгалтерського обліку.
Q10: Який один найкращий спосіб уникнути катастрофічних повторних пересилань?
Resumable реплікація плюс моніторинг resume токенів і лагу. WAN-лінки впадуть; ваш план має це передбачати і зберігати прогрес.
Висновок
Швидка реплікація ZFS через повільний WAN — це не один чарівний прапорець. Це про те, щоб зробити конвеєр нудним: передбачувана частота снапшотів, інкрементальні стрими, буферизація для джиттера, правильний вибір шифрування/стиснення і приймач, що справді встигає записувати те, що ви відправляєте. Найкращі налаштування не просто швидкі в гарні дні — вони продовжують рухатися в погані дні, відновлюються після переривань і рано попереджають, коли реальність відходить від вашого RPO.
Якщо ви візьмете лише один операційний урок: вимірюйте кожну стадію, швидко ізолюйте вузьке горло і оптимізуйте те обмеження, яке у вас є — а не те, яке здається вам знайомим.