Синхронізація часу і дрейф
1) Чому час - архітектурний компонент
Час потрапляє в усі шари: TTL токенів і сертифікатів, дедлайни RPC, порядок подій, логи і аналітика, консенсус і блокування. Помилка на десятки-сотні мілісекунд може:- ламати Kerberos/OAuth/JWT (поля'iat/nbf/exp');
- спотворювати метрики/трейси та алерти;
- кидати брокери/клієнтів (таймаути, ретраї, експоненціальний backoff);
- порушувати порядок та ідемпотентність у розподілених сценаріях.
- Offset (зміщення) - різниця локального часу від еталона.
- Skew (роз'їзд) - різниця офсетів між вузлами.
- Drift (дрейф) - швидкість догляду годин (ppm) при відсутності корекції.
- Jitter - варіативність затримок/вимірювань.
2) Джерела та протоколи часу
2. 1 NTP (Network Time Protocol)
Страти (Stratum 1 - безпосередньо від GNSS/радіо, Stratum 2 - від Stratum 1, і т.д.).
Налаштування двома способами:- slew (плавне підлаштування частоти, безпечно для додатків);
- step (стрибок часу; небажаний на проді).
- Реалізації: chrony, ntpd, systemd-timesyncd. Для серверів - переважно chrony.
2. 2 NTS (NTP over TLS)
Автентифікована синхронізація (захист від MITM і підміни часу).
Рекомендується для зовнішніх серверів часу.
2. 3 PTP / IEEE 1588
Апаратні мітки часу (hardware timestamping) в NIC/ToR, мілі- і мікросекундна точність.
Режими: boundary/transparent clock, профілі телеком/ентерпрайз.
Використовувати при жорстких SLO на p99-порядок, HFT/телеком/індустрія.
2. 4 GNSS (GPS/ГЛОНАСС) і PPS
Локальні приймачі дають PPS (pulse-per-second) еталон для Stratum 1.
Важливо враховувати спуфінг/глушіння - ставити антени і моніторити цілісність.
2. 5 Хмари
Хмарні джерела (внутрішні stratum-пули) зменшують офсет і джиттер всередині VPC.
Для гібридних середовищ - комбінуйте локальні та хмарні референси.
3) Час в ОС і залозі
TSC/HPET/RTC: сучасні CPU тримають TSC як швидкий монотонний лічильник; закріплюйте частоту (invariant TSC).
Віртуалізація/контейнери: дрейф і «стрибки» частіше. На гіпервізорі - строгий тайм-сервіс; в гостях - chrony.
Енергозбереження може заважати монотонії таймерів - перевіряйте BIOS/UEFI опції.
4) Монотонний і «стінний» годинник
Wall-clock (реальний час, TZ/UTC) - для логів, міток подій, людей.
Monotonic clock - для вимірювання інтервалів/таймаутів.
- Linux: `CLOCK_MONOTONIC`.
- C++: `std::chrono::steady_clock`.
- Go: вбудовані монотонні частини'time. Time'в інтервалах.
- Java: `System. nanoTime ()'для тривалостей, не для календаря.
Правило: дедлайни і ретраї - на монотонних годинниках; серіалізація/логування - на UTC.
5) Leap second/» leap smear» і календарні пастки
Leap second може викликати "00:59:60" або повтор секунди → петлі в таймерах/метриках.
Підходи:- Smear (плавна «розмазка» секунди за N годин).
- Крок (небажаний).
- Ніколи не покладайтеся на локальні TZ/літній час для логіки; зберігайте UTC, показуйте в TZ користувача.
- Оновлюйте TZDB (база часових поясів) - політичні зміни трапляються.
6) Узгодження порядку без довіри до «стіни»
Lamport clocks і Vector clocks - причинно-наслідкові відносини без фізичних годин.
Hybrid Logical Clocks (HLC) - об'єднують фізичний час і лічильник, стійкі до невеликого skew.
TrueTime-подібні моделі - повертають інтервал'[ earliest, latest]'і вимагають commit-wait для серіалізації.
7) Вплив часу на протоколи і системи
Безпека: Kerberos допускає невеликий skew (зазвичай ± 5 хвилин), TLS/сертифікати чутливі до'notBefore/notAfter', JWT до'exp/nbf/iat'.
Брокери/черги: дедлайни задач/visibility timeout залежать від правильного часу.
СУБД/кластери: конфлікт версій по'updated _ at '/ts - вводьте HLC/версії, а не порівнюйте «сирі» wall-timestamps.
Стрімінг: розрізняйте event time і processing time; налаштовуйте watermarks і lateness.
Крон/планувальники: дрейф веде до «залипання »/подвійних запусків. Використовуйте монотонні інтервали і дедуп ключі.
8) Спостережуваність і SLO часу
8. 1 Метрики
`time. offset_ms' (офсет до референсу),'time. jitter_ms`, `stratum`, `root_delay`, `root_dispersion`.
Для PTP: `path_delay`, `grandmaster_offset`, `gm_identity`, `clock_class`.
Алерти: офсет> порогу (наприклад, 100-500 мс), втрата джерела, step-корекції.
8. 2 Діагностика
`chronyc tracking/sources/sourcestats`
`ntpq -p`, `ntpstat`
PTP: 'pmc', вендорні утиліти NIC/ToR.
8. 3 SLO/помилковий бюджет
Приклад SLO: "median offset ≤ 1 ms, p99 offset ≤ 25 ms, no step на прод-вузлах; PTP grandmaster failover ≤ 2 s».
9) Практики конфігурації (Linux/containers/K8s)
9. 1 chrony (рекомендується)
Приклад ('/etc/chrony/chrony. conf`):
pool time. example. org iburst maxsamples 9 nts makestep 0. 5 1 # one step at big error at start rtcsync # synchronize hardware clock leapsectz right/UTC # leap seconds from tzdata driftfile/var/lib/chrony/drift
Корисні опції:
- `maxsources`, `minsamples/maxsamples`, `maxslewrate`.
- Для ізольованих DC - локальний референс + GPS/PPS.
9. 2 Контейнери та вузли
Синхронізацію робіть на хості; контейнери використовують ядро.
У K8s - DaemonSet з chrony або node-level тайм-агент; забороните привнесення часу додатками.
9. 3 PTP стек
NIC з апаратним timestamping, PTP-демон, boundary clocks на ToR.
Рознесення доменів PTP (профілі), захист від «поганих» grandmaster.
10) Безпека часу
NTS/автентифікований NTP, фільтри і rate-limit (NTP-посилення - вектор DDoS).
PTP security: ізоляція L2, ACL на мультикаст, моніторинг GM spoofing.
GNSS: антени з хорошим оглядом, детект спуфінгу/джамінгу, fallback-джерела.
11) Інженерні патерни та код
11. 1 Дедлайни/таймаути
Зберігайте дедлайни як «монотонний старт + дельта», а не абсолютний wall-timestamp.
Завжди додавайте запас на skew (наприклад, 2 × очікуваного p99-skew до TTL токена).
11. 2 Порівняння версій
Не покладайтеся на'updated _ at'між вузлами. Використовуйте:- версіонування/ETag;
- HLC/seq;
- оптимістичні блокування.
11. 3 Логи і трасування
Завжди UTC; вмикайте поле'time _ offset _ ms'вузла в логи агента.
Проклеюйте event-time в подіях трасування.
11. 4 Обробка leap second
Виберіть політику (smear/step) однаково по всіх вузлах.
Тестуйте: метрики не повинні «ламатися» на повторній секунді.
12) Вплив на домени
Auth: токени - враховуйте «clock skew allowance» (наприклад, ± 2-5 хвилин).
Payments/відрізки часу: округлюйте інтервали, а не абсолютний час.
Брокери: розклади ретраїв - на монотонних годинниках.
БД/TTL: TTL в Redis/DB - спирається на локальний годинник: Закладайте запас.
Аналітика: агрегації за часом - використовуйте єдиний UTC і синхронізацію ingestion.
13) Тест-плейбуки (Game Days)
Drift injection: штучно відвести годинник на +/−Δ; перевірити auth, брокери, SLO.
NTP outage: вимкнути джерела, простежити drift і автопереключення.
Leap second/smear: імітація настання leap, оцінка графіків/таймерів.
PTP GM failover: перевірити час перемикання і офсет після.
VM suspend/resume: переконатися у відсутності «стрибків» і step на гостях.
14) Анти-патерни
Порівнювати події різних вузлів за wall-часом без HLC/seq.
Класти «рядкові локалі» часу (з TZ) в БД замість UTC.
Дозволяти додаткам робити'date -s '/' timedatectl set-time'.
Включати step-корекції на проді без планування.
Ігнорувати оновлення TZDB та правила переходу на літній час.
Використовувати wall-clock для backoff/таймаутів/токен-TTL без запасу на skew.
Намагатися «лікувати порядок» фізичним часом замість логічних годин.
15) Чек-лист впровадження
- Єдина політика: NTP (з NTS) або PTP; список довірених джерел.
- Вузли налаштовані на slew, step тільки на старті.
- Єдина політика leap second (smear/step) за всіма кластерами.
- Моніторинг офсету, джиттера, stratum/PTP показників; алерти.
- Додатки використовують монотонний годинник для інтервалів/дедлайнів.
- Для порядку/конфліктів - HLC/версії, не wall-timestamps.
- Запаси на skew в TTL токенів, сертифікатах, розкладах.
- K8s/VM: синхронізація на хостах, контейнери без прав змінювати час.
- Документація і runbooks з відмов часу, game days в CI/CD календарі.
- Регулярні оновлення TZDB, перевірка поведінки при DST/leap подіях.
16) FAQ
Q: Коли потрібен PTP замість NTP?
A: Коли SLO вимагає мікросекунд-десятків мікросекунд (телеком/HFT/індустрія) і є підтримка апаратних міток в мережі/картах.
Q: Скільки закладати на clock skew?
A: Для типового NTP в DC - десятки-сотні мс (p99); закладайте 2 × запасу. З PTP - одиниці-десятки мкс.
Q: Як пережити leap second?
A: Використовувати smear і однакову політику скрізь; протестувати графіки/агрегатори і таймери.
Q: Чи можна покладатися на wall-clock для дедлайнів?
A: Ні, ні. Тільки монотонний годинник + запас на skew.
Q: Як зберігати «час» в БД?
A: В UTC ('timestamptz'), плюс версії/HLC для вирішення конфліктів; не зберігайте локальні зони в даних.
17) Підсумки
Надійний час - це протокол + політика + дисципліна в коді. Синхронізуйте вузли (NTP/NTS або PTP), використовуйте moнотонні годинники для інтервалів, UTC для даних, HLC/версії для порядку, закладайте запаси на skew, моніторьте офсет і регулярно проводьте game days. Так ви уникнете «містичних» багів автентифікації, розбіжностей в подіях і нестабільних SLO.