Потокові ML-пайплайни для real-time інференсу на Kafka, Flink і ONNX

Ми розробляємо потокову обробку даних під ключ: події доходять до рішення без затримок навіть на піках навантаження. Скорочуємо час реакції систем у рази, а обсяг ручної роботи — на 60%. Залишаєтесь з працюючим контуром, схемами та регламентами.
Часті запитання

Чому потокова обробка даних ламається на піках

Потокова обробка даних ламається не на самому піку, а трохи раніше — коли черга ще тримається, а затримка обробки подій уже вийшла за допустиму межу.

Пікове навантаження на контур надходить нерівномірно: зовнішні джерела та внутрішні сервіси віддають події в середньому рівномірно, а короткими інтервалами — у рази швидше. Конвеєр тримається до того моменту, поки швидкість читання збігається зі швидкістю запису.

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

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

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

Зворотний бік гарантій доставки — дублі подій. Під час перерозподілу споживачів усередині групи або повторної доставки одна подія потрапляє в обробку двічі, і віконний агрегат рахує її як дві.

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

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

Усі три збої — про контур, а не про модель: вони проявляються лише під навантаженням і майже не відтворюються на тестовому потоці. Нижче розбираємо, як це закривається на рівні конвеєра та контролю над ним.

Що дає потоковий контур: вимірюваний ефект

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

Зниження затримки передбачень

Ознаки збираються в ковзному вікні, модель відповідає на тій самій події, результат одразу йде у вітрину та в сервіс-споживач. Пакетний перерахунок дає відповідь через хвилини або години, потоковий — у межах секунди від події, і затримка не зростає разом з обсягом потоку.

Прибраний клас відмов: втрати та дублі

Транспортом слугує Apache Kafka: підтвердження доставки та ідемпотентний запис за ключем події усувають цілий клас відмов — повідомлення не губляться під час перезапуску споживача й не задвоюють передбачення.

Після падіння вузла контур продовжує зі збереженої позиції, без ручної звірки та повторного прогону накопичених даних.

Скільки ручної роботи знімає автоперерахунок

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

Спостережуваність контуру — відставання споживача, затримка кожної ділянки, частка відхилених записів — перетворює розбір збою на читання метрик. Помилку видно до того, як вона дійде до користувача.

Способи доставки подій: що вибрати під задачу

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

Пакетний режим за розкладом

Перерахунок читає накопичений зріз, рахує агрегати та записує результат цілком. Обмеження — затримка дорівнює інтервалу запуску, а сплеск даних зсуває наступне вікно. Для звітності, перерахунку ознак і навчання моделей це найпередбачуваніший варіант.

Мікропакети та чиста потокова схема — де межа

Мікропакет збирає події за коротке вікно й віддає пачкою: затримка — секунди, вартість близька до пакетної.

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

Варіант Коли підходить Обмеження
Пакетна обробка за розкладом Звітність, перерахунок ознак, навчання Затримка дорівнює інтервалу запуску
Мікропакетний режим Метрики та вітрини із затримкою в секунди Запізнілі події ускладнюють логіку
Чиста потокова схема Скоринг, реакція на аномалію Стан, повтори, ціна експлуатації
Гібридний контур Швидка відповідь плюс фоновий перерахунок Потрібна звірка потокового й пакетного підсумку

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

Вибір режиму обробки закладаємо в архітектуру заздалегідь — перевести сервіс з пакета на потік пізніше дорожче, ніж одразу передбачити гібрид.

Як ми розгортаємо потоковий контур: етапи робіт

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

Аудит джерел і профілю навантаження

  1. Аудит джерел даних — інвентаризація топіків, форматів повідомлень, ключів партиціювання та частки «брудних» записів. На виході — карта джерел із позначками про затримки та зміни схем, що ламають зворотну сумісність.
  2. Профіль навантаження — знімаємо реальний потік: піки, сезонність, розподіл за ключами. Звідси рахуємо кількість паралельних обробників і запас за пам’яттю.
  3. Схема потокового контуру — фіксуємо межі: де читаємо, де збагачуємо, де викликаємо модель, де зберігаємо. Окремо описуємо семантику доставки та порядок перегравання вікна під час збою.

Перевірка на тіньовому трафіку перед перемиканням

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

Що залишається у вас: схеми, регламенти, конфігурації

Віддаємо контур не «працюючим», а обслуговуваним: інженер замовника має сам підняти потік, додати поле в подію й відновитися після збою, не чекаючи на нас.

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

Схеми потоків та опис форматів подій

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

Регламенти реакції на збої

  • Рівні інцидентів і час реакції за кожним: відставання потоку, втрати подій, відмова моделі на інференсі.
  • Порядок дій: як зупинити приймання, переграти відрізок з останньої точки збереження, відкотити версію схеми або моделі.
  • Правила доступу до даних: ролі, з чого зібрано доступ до кожного потоку, де зберігаються ключі та як вони змінюються.
  • Документація контуру: схема розміщення, залежності, власники потоків, порядок внесення змін.

До кожного пункту додається короткий перелік перевірки — замовник приймає роботу сам, а не на слово.

Кейс: як скоротили затримки на піку навантаження

Клієнт — платформа, де на кожну подію від пристроїв модель зобов’язана відповісти всередині того самого запиту.

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

Що було до і що стало після

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

Стан вікон винесли у відмовостійке сховище, і рестарт вузла перестав означати втрату накопиченого контексту.

Метрика До Після
Затримка передбачення на піку зростання в 12 разів зростання в 1,4 раза
Частка втрачених подій 3–4 % у годину пік 0,02 %
Відновлення контуру після відмови вузла 20–35 хвилин до 40 секунд

Повторну обробку зробили ідемпотентною: у кожної події є ключ, тому перегравання журналу не дає дублів у сховищі та роз’їзду агрегатів. Саме цей клас відмов давав подвійні записи після збою й змушував інженерів вручну звіряти вітрини.

Чим потокова обробка відрізняється від пакетної?

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

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

Затримка задає межу застосовності. Поки відповідь приходить раз на добу, скоринг у момент заявки, алерт за аномалією або підказка в інтерфейсі неможливі.

Потік зсуває відгук до секунд, але платить за це постійною роботою контуру: він тримає стан агрегатів між подіями й не «засинає» між запусками.

Перерахунок історичних даних — сильна сторона пакетного підходу: змінюємо логіку, перезапускаємо період, отримуємо узгоджену картину.

У потоці це окрема операція — відновити стан на потрібний момент, обмежити вікно та зробити запис ідемпотентним, інакше повторна обробка подвоїть лічильники й спотворить вітрину.

Складність налагодження в потоці вища з об’єктивної причини. Пакетний розрахунок відтворюваний: є вхідний зріз, версія коду та результат.

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

Вимоги до якості даних розходяться так само: у пакеті битий запис ізолюють, виправляють і перераховують, а в потоці несумісне поле ламає обробку на льоту.

Тому контури не протиставляють, а поєднують: потік відповідає за свіжість, пакет — за повноту та звірку. Вибір диктує не обсяг даних, а допустима затримка результату та ціна помилки.

Часті технічні сумніви перед стартом

Перед стартом інженерні команди ставлять ті самі запитання: що станеться із запізнілими подіями, як не задвоїти результати під час повторної доставки, чи витримає контур зростання потоку. Нижче — короткі відповіді про те, як ці ризики закриваються в потоковій обробці на практиці.

Що відбувається із запізнілими подіями?

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

Як забезпечується ідемпотентна обробка?

Кожне повідомлення несе ключ, а запис результату виконується з перевіркою цього ключа, тому повторна доставка не створює дубль. Під час перезапуску конвеєр продовжує з останньої підтвердженої позиції — збій не перетворюється на задвоєні значення у звітності.

Як контролюється якість даних?

На вході ставимо перевірки схеми, діапазонів і обов’язкових полів, аномалії не ронять потік, а позначаються й ідуть у карантин. Частка відбракованих записів і причини потрапляють у моніторинг, тож деградація джерела видна до того, як дійде до моделей.

Чи витримає контур зростання навантаження?

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

Як запускаєте без ризику для продакшену?

Йдемо поетапно: спочатку тіньовий прогін на копії потоку та звірка результатів з поточним контуром, потім поступовий перевід частки трафіку зі збереженням зворотного перемикання. Відкат — це повернення на попередній маршрут, а не відновлення з бекапу.

Обговоримо задачу та повернемося з оцінкою і планом

Для змістовної розмови не потрібен готовий документ — достатньо опису того, як потік даних живе зараз. Чим конкретніші вхідні, тим точніша оцінка та план робіт.

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

У відповідь ми надсилаємо оцінку та план робіт: розбивку за етапами з тривалістю, схему руху даних, перелік ризиків і точки відкату, склад команди та зону відповідальності на вашій стороні.

Якщо за вхідними видно, що частину контуру переробляти не потрібно, скажемо про це прямо — це скорочує обсяг робіт.

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

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141