Любому бизнесу не нравится терять деньги — в этом смысл бизнеса. Каждая партия брака — это потраченные время и ресурсы, упущенная прибыль. Тогда бизнес приходит и говорит: «Давайте как-то измерять показатели, чтобы вовремя что-то менять, видеть всё это в реальном времени, и, главное — на основе данных». Так как же осчастливить сразу бизнес, разработчиков и себя?

Привет, Хабр! Я — Павел Лукьянов, системный архитектор и Deputy CTO в AGIMA. За семь лет работы в отрасли придумал много разных проектов, в том числе, с высокой нагрузкой — от Госуслуг до АльфаСтрахование, и поработал с разными сферами. Подробнее об этом вы можете ознакомиться в моём тг-канале, где публикуются «записки ударника труда» программиста с опытом 7+ лет.

В этой статье по мотивам доклада с Saint HighLoad++  на примере одного из реальных кейсов с большим количеством внешних систем для сбора данных расскажу, как их собирать и обрабатывать, представлю готовые импортозамещённые инструменты для систематизации и хранения. Кроме того, покажу, почему не стоит заморачиваться из-за безопасности и по какой причине бизнесу важно следить за проектом в реальном времени и принимать решения.

Я был на проекте архитектором: мы пройдём мой путь.

О чём проект? 

Есть отрасль по производству удобрений. На одном из заводов появилась задача: нужно измерять параметры гранул для того, чтобы менять их состав в зависимости от размера. Это важно для бизнеса, чтобы определять брак. Тут мы начинаем погружаться в контекст системы.

Контекст проекта

На производстве отдельная служба, метрологическая, раз в день проводит замеры гранул и решает, всё ли ок.

Как было до? 

Есть конвейер, в нём — вагонетки, в которые из печи сверху сыпятся гранулы, конечный продукт. В дальнейшем он идёт по технологическому пути: попадает в мешки, мешки — в грузовики, грузовики — в коробки, коробки — в ящики.

Мы смотрим на брак гранул до мешков. Проблема в том, что у бизнеса нет контроля на ранних этапах. Состав каким-то образом готовится, сыпется, но это не контролируется никем, кроме метрологической службы, которая делает это раз в день. Без контроля на ранних этапах мы не управляем качеством, а лишь фиксируем последствия.

Основная идея проекта на основе данных помочь бизнесу в принятии оперативных производственных решений.

Наша цель как разработчиков — помочь бизнесу в переходе от догадок и хаоса в мешках к данным и прогнозам в BI-инструменте.

Deep dive в проблему

Давайте заглянем в эту кроличью нору. Что пришло на ум бизнесу? Натыкать камер, которые будут измерять размер гранул, и на основе этих данных принимать решения. Вроде просто, но порождает кучу вопросов:

  • Как измерить качество гранул на лету?

  • Какие данные нужны, чтобы принимать решение?

  • Где и как это отображать в реальном времени?

Важно: каждая вагонетка — это около 500 кг гранул, каждый из которых, как и затраченное сырьё, стоит денег. А также есть рабочие, электричество, оборудование с износом и т.д. — бизнес снова теряет деньги.

Основная мысль: пока мы «ждём день», тратятся реальные ресурсы. А когда бизнес работает вхолостую, мы приходим ещё и к экологической проблеме.

Картинка с пингвинчиком показывает, что мы всё-таки, как разработчики, жалеем бизнес.

При этом идея с камерой — клёвая, но камеры — высокоскоростные. Ещё вернёмся к тому, какой поток они генерируют, пока скажу лишь, что они создают очень много потока:

  • Каждая камера — это десятки терабайт в день.

  • В сумме — петабайт данных в сутки и больше.

  • Без ограничений система захлёбывается.

В сумме звучит как план, который можно выполнить, но мы приходим к петабайту данных. У бизнеса на данном этапе (в момент подготовки доклада) нет никаких ограничений — это всё терабайты, их нужно где-то разместить. При этом помним, что это завод.

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

Погружу вас в то, как мы проходили путь с железом.

Время уходить в «техничку»

Любая система состоит из различных представлений, которые нужно понимать для дальнейшей реализации.

Типы представлений системы

  1. Представление контекста (Context View)

Высокоуровневое описание взаимодействий с внешними системами и группами пользователей.

Мы примерно представляем верхний уровень: с какими внешними системами будем интегрироваться, какими будут группы пользователей и что они будут делать в системе.

  1. Логическое представление (Logical View)

Оно сфокусировано на функциональности, предоставляемой системой для конечных пользователей. По сути это второй уровень С4 нотации.

Обычно это первый и второй уровень C4 — их достаточно, чтобы описать контекст системы и логические взаимосвязи внутри системы.

  1. Представление нефункциональных требований (Non-functional View)

В этом разделе описаны архитектурно значимые параметры, объёмные и временные характеристики системы.

Следом нам нужно упорядочить нефункциональные требования. Вы можете сказать, что есть аналитики, они ведут реестр нефункциональных требований, управляют ими. Нас, как архитекторов, это интересует, чтобы первые два представления были актуальны и подходили для нагрузки и для нефункциональных предъявляемых требований.

  1. Физическое представление (Physical View)

Представление физической структуры показывает систему с точки зрения системного инженера, распределение программных компонентов по физическим уровням и физические каналы связи между уровнями.

Physical View известно также как представление развёртывания системы. Представление физической структуры системы использует UML-диаграмму развёртывания. Это то, как система физически расположена на серверах, где они находятся, какие это дата-центры, тачки, виртуалки, куберы.

  1. Прогноз по вычислительным мощностям

Описывает предварительные требования к выделяемым для размещения сервиса мощностям в разрезе виртуальных машин. Если проект вышёл на развитие — указываем показатели as is.

Основная цель — как можно раньше заявить о доп. ресурсах (при необходимости), чтобы заказчик мог заранее спланировать бюджет. Из физического представления мы получаем прогноз по мощностям, чтобы сделать некий форкаст,  сколько денег там в будущем нужно потратить.

  1. Представление информационной безопасности (Security View)

Описывает элементы системы и функциональность, которая влияет на информационную безопасность системы.

ИБ всегда рядом, для них нужно отдельно это всё описывать.

  1. Операционное представление (Operational View)

Описывает систему с точки зрения её поддержки в продуктивной среде, в том числе релизную модель и hotline-метрики.

Мы реализовали систему, а теперь нужно понять, как её операционно поддерживать, какие есть hotline-метрики, как за ней наблюдать и что делать в случае неполадок.

Контекст

Как я сказал, есть некая видеоаналитика, что происходит вокруг. И есть две камеры: высокоскоростная и камера глубины.

Когда мы задумались, какие параметры нам нужны, поняли, что мало просто измерять гранулы при помощи снимков — нас интересует фактический объём гранул внутри вагонетки.

Например, есть некий ARM, в который должен смотреть пользователь и что-то делать.

Дальше схема обрастает новыми блоками. Обычно на заводах есть некая платформа, куда нужно отправлять информацию. Команде DWH нужны данные — они хотят получать ещё и ваши. Соответственно, если есть внешняя платформа, значит, есть ARM, который с этой платформой взаимодействует и тоже что-то хочет увидеть.

В логической схеме мы получаем следующую ситуацию:

У нас есть:

  • База, где мы храним данные

  • Оркестратор для обработки данных с камер (здесь Apache NiFi) 

  • Хранилище изображений (здесь MinIO) 

  • UI

Внезапно это Grafana. Оказалось, что Power BI, Tableau (импортные), Metabase и т.д. избыточны — на заводе уже есть Grafana и к ней можно подключиться.

 Почему NiFi, а не Airflow?

  1. Потоковая обработка: можно обрабатывать данные в режиме real-time или batch.

  2. Visual Flow Designer: интуитивная настройка коннекторов (FTP, HTTP, Kafka, файловые системы, JDBC и т. д.).

  3. Механизмы контроля потока: back-pressure, приостановка потоков, реплей событий.

  4. Возможность оркестрации: запуск сторонних процессов или передача данных в Python/ML/др.

  5. JOLT Transform.

Основная причина, по которой был выбран, в том числе, NiFi, а не Airflow — желание  использовать преимущество no-кода. Основная фишка NiFi в том, что помимо потоковой обработки у него есть веб-интерфейс, где можно low-code методом собирать сложные пайплайны.

Более того, так как это оркестратор, он всё ещё позволяет нам запускать сторонние процессы. А мы помним, что работаем с камерами. У нас есть уже готовый оркестратор, который мы можем попробовать переиспользовать. При этом в NiFi уже есть разные удобные фичи наподобие JOLT Transform.

Так как это low-code, visual-code решение, там уже есть встроенные механизмы отказоустойчивости (приостановка потоков, управление внутренними очередями и т.д.).

Важный момент: различия NiFi и Airflow ещё и в том, что Airflow работает в основном на CPU и на RAM, а NiFi — на жёстких дисках. Это важно в контексте обработки данных.

Польза решения

Управляемость системы:

  • Обладает удобным интерфейсом для мониторинга.

  • Предусматривает возможность настройки уведомлений о сбоях.

Совместимость системы:

  • Интегрируется с источниками и целевыми системами PostgreSQL, MySQL, ClickHouse, Redis.

  • Взаимодействует со скриптами, написанными на языке Python 3 (версии от 3.11).

  • Поддерживает форматы данных JSON и CSV.

  • Дружит с ML-моделями.

Масштабируемость системы:

  • Предусматривает возможность горизонтального и вертикального масштабирования для обработки увеличивающегося объёма данных. Может работать в кластерном режиме через ZooKeeper

  • Поддерживает кластеризацию для распределения нагрузки между несколькими узлами NiFi.

Надёжность / отказоустойчивость:

  • Автоматически восстановливается после сбоев.

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

И тут вы, посмотрев на эту схему, скажете: а где тут HighLoad? Система выглядит миниатюрной.

Нефункциональные требования к ПО

Примерно так выглядели аналитик проекта, архитектор и в каком-то смысле Project Manager.

  • В соответствии с Федеральным законом от 26.07.2017 No 187-ФЗ «О безопасности критической информационной инфраструктуры Российской федерации» система должна использовать ПО из Реестра российского программного обеспечения.

Объект КИИ. Действуют 17 и 22 ФСТЭК!

Поскольку завод — это объект КИИ, мы сталкиваемся с набором различных ФЗ. Первое, что бросается в глаза — это 17 и 22 ФСТЭК, а также импортозамещение и невозможность использовать «вражеские технологии», как их сейчас называют. А также требования, предъявляемые к объектам критической инфраструктуры.

  • Хотя у нас есть ML-модели, их переобучение возможно только с использованием актуальных данных с прода. У нас нет возможности ретроспективно научить модель на наборе датасета с гранулами и спокойно её деплоить. Это ограничение связано с тем, что у нас высокоскоростные камеры и частота снимков слишком большая.

  • Система должна обрабатывать данные с высокоскоростных камер с количеством кадров в секунду не менее 20. Общее количество передаваемых кадров в секунду с камеры — 40.

Для решения задачи нам нужно в общем случае 40 кадров в секунду с камеры и всего 20 камер (10 высокоскоростных и 10 глубины). Умножаем на 20, и сталкиваемся с первой проблемой — это большой объём.

  • Допустимая погрешность в день в сравнении с данными метрологической службы предприятия — 10% при частоте замеров раз в 12 часов.

У заказчика есть чёткое условие: необходимо добиться той же точности, что и у метрологической службы, иначе система теряет смысл, а человек становится дешевле.

Эти требования вгоняли в депрессию, потому что другого способа мы не нашли.

Но есть и хорошие новости!

Мы ещё раз взглянули на требования — факт того, что это всё-таки класс критичности business operations слегла развязал руки в части репликации, сохранности и и.д.

Мы с заказчиком для облегчения осознанно добавили допустимую задержку обработки снимков в 30 минут. В пике система имеет три пользователя, но мы хотели ещё больше всё упростить и взяли встроенный RBAC технологии Grafana — интеграция с AD предприятия не требуется, ничего не нужно настраивать.

Вы спросите, а как же ИБ? Я скажу, что нет интернета — нет проблем.

Дальше на схемах будет подписано, в каком цеху это находится. 

Это физическое помещение, в котором физически нет доступа во внешний мир. Соответственно, не нужно уходить в сложные ГОСТы — мы просто говорим, что у нас нет доступа, заходит только определённый набор доверенных инженеров. Это и есть векторы атак. Мы отсекаем сразу кучу векторов, предлагаем использовать RBAC и Grafana и ИБ соглашается.

Перейдём к физической диаграмме.

Физическая диаграмма

Система выглядит маленькой, и вероятно, что она в этом помещении будет также небольшой — 10 одних камер, 10 других, коммутатор.

И тут мы сталкиваемся с тем, что у нас 10 нод NiFi, находящихся на bare-metal внутри этого помещения.

Здесь стоит упомянуть отдельно о том, что мы выбрали NiFi ещё и потому, что у него очень хорошая документация.

Скриншот из документации, где говорится, сколько нужно дисков, CPU, RAM, чтобы была отправная точка.

Посмотрите на объём данных, которые будут проходить, и запомните эту цифру. В названии доклада было слово «петабайт» — в конце я скажу, почему там не он.

Есть ещё более подробная документация, в которой эти же физические ресурсы уже транслированы на объём данных, которые проходят в день, и на объём событий, которые может обрабатывать одна нода. Таким нехитрым образом получаем 10 нод.

Полная диаграмма, чтобы оценить компактность:

Диаграмма специально выглядит такой маленькой, чтобы все схемы выглядели простыми. А вся сложность проекта заключается в том, что пришлось поиграться с нефункциональными требованиями. Несколькими абзацами выше я сознательно попросил запомнить цифру — где петабайт?

Инсайты, факапы, неожиданные открытия

Разберёмся, зачем нужно было так подробно останавливаться на описаниях схем, видах представлений и т.д.

Почему мы делаем полный набор представлений даже для маленьких систем

  1. Формализация архитектуры помогает зафиксировать границы и договорённости

Система действительно была на петабайт данных. Изначально заказчик даже сам приходил и говорил, что будет или столько, или даже больше. Но благодаря формализации архитектуры можно с кем угодно договориться и за счёт этого сократить ненужные объёмы.

  1. Каждое представление — это фокус на отдельном аспекте: от взаимодействий до операционного сопровождения.

Когда система разрезается на различный набор представлений, это позволяет фокусироваться на разных её частях и искать точки оптимизации. Все эти представления важны.

  1. Security и NFR — не «опции», а необходимость с первых шагов.

Те же самые нефункциональные представления ИБ, по сути, самые важные, потому что остальные вырастают из них и позволяют оптимизироваться.

  1. Прогноз мощностей и точка входа в бюджет экономят ресурсы ещё до запуска.

Это про деньги за сервера, потому что там был bare metal. В факапах ещё будет о том, сколько он стоил.

  1. Архитектура становится картой реальности, а не догоняющим артефактом.

Доклад разделён на две части: первая часть — о готовых инструментах, которые мы затронули (NiFi, Grafana, MinIO). Это всё уже готовые коробки, которые можно поставить и они будут выполнять свою задачу. В дальнейшем задача заключается в том, чтобы их правильно приготовить и оптимизировать.

  1. «Хотелки» трансформируются в обоснованные требования.

Вторая часть доклада скорее про архитектурный путь — как эти требования реализовать в понятную схему и зафиксировать границы и обоснования всех пожеланий.

  1. Мы управляем изменениями, а не ловим их постфактум.

Пожеланий может быть много, и мы должны управлять этими изменениями, чтобы не заложить слишком много или, наоборот, переоптимизироваться и срезать лишнее.

  1. Бизнес сам ограничивает себя через понимание и прозрачность.

На самом деле, не мы ограничиваем бизнес, как разработчики, а сам бизнес в определённый момент понимает, что частью требований, которые он изначально хотел закладывать, можно пренебречь.

Архитектурные представления — это не бюрократия, а инструмент зрелости и осознанного проектирования, даже если система небольшая.

Все представленные в докладе иллюстрации были картой и переиспользовались на четырёх разных проектах со схожими требованиями. Это означает, что когда вы получаете классную архитектуру, это показывает зрелость проекта, в том числе, бизнесу, и позволяет вкладывать больше денег.

Куда же делся петабайт данных 

Почему на картинке было жалких 300 терабайт в день?

  • Железо не бесплатное

Мы уже обсуждали, что нанять человека будет дешевле — бесконечно раздувать инфраструктуру ради гипотетического предела не получится, особенно при импортозамещении.

  • Ограничили поток с камер

Я говорил о потоке 40 кадров в секунду, но сами камеры генерируют 6400 кадров в секунду. Мы ограничили поток и теперь выясняем, какие кадры нужны и когда. Так мы смогли пренебречь кластером MinIO.

  • Рационально подошли к отказоустойчивости

Я упоминал о классе критичности системы Business Operation — это позволило нам не делать кластер. Вместо сложных сценариев репликации решили поиграться с RAID-массивами на SSD, потому что в целом вся система построена вокруг жёстких дисков. MinIO, NiFi, ClickHouse — это всё жёсткие диски. За счёт этого у нас есть единая точка, в которой мы можем как скейлиться, так и оптимизироваться. Просто, надёжно, управляемо.

Кроме того, RAID-массивы — это рациональный способ сохранять данные, но  при этом не закладывать катастрофоустойчивость, когда есть второй дата-центр с огромными объёмами. За счёт этого оптимизировались косты.

Важный момент: это никоим образом не выводит систему из HighLoad. Там три пользователя, которые смотрят в графики, но поток данных может изменяться и система поддерживает это расширение. Сейчас она выстраивалась вокруг наложенных бизнесом ограничений, но при этом учитывается, что бизнес после обкатки MVP может захотеть, например, весь поток сохранять, масштабировать эту систему на несколько заводов и т.д.

Важный факап

Мы посчитали сайзинг — в условиях импортозамещения это оказалось очень дорого. Сам проект стоил в три раза дешевле. Тогда мы с бизнесом решали уже не проблему костов разработки, а костов железа.

На самом деле, сайзинг стоил столько, потому что существуют методы диверсификации подрядчиков и т.д. Мы решили и этот вопрос — сайзинг стал дешевле. Более того, для аналогичной системы с иной конфигурацией мы уложились в меньшую сумму. Это очень хорошая, крепкая цифра для того, чтобы обрабатывать поток данных с высокоскоростных камер.

Интересное наблюдение

Я уже обмолвился, что данная архитектура переиспользовалась. На картинке — счастливый архитектор, даже грейдом ниже. Он получил готовый набор кубиков, с которыми ходит по проектам.

Условно, его задача была в том, чтобы посмотреть на нефункциональные требования, выяснить их вместе с системным аналитиком и примерить готовые кубики на нефункциональные требования. У него были понятные точки оптимизации и расширения — он ими просто управлял в зависимости от проекта. Это не означает, что четыре проекта были полностью одинаковые. Скорее, что объём работы уменьшился — для текущего проекта четыре месяца, для следующего — уже один.

Фактически, готовые инструменты плюс готовый шаблонизированный набор архитектурных артефактов позволяют ускорить разработку проекта.

Зачем я это всё рассказал? 

Стоит помнить, что любая разработка систем — это непростые решения с двух сторон:

  • Разработчики — это про бэклог, про оптимизацию. Хочется отрефакторить код, написать микросервис, чтобы они через Kafka общались и было очень круто.

  • Бизнес хочет дешёво, быстро, «вчера», и красиво.

На картинке — версия уставшего меня как архитектора и счастливого бизнеса. Когда две стороны принимают осознанно непростые решения, обе становятся счастливыми.

При этом важно помнить:

  • Даже маленькая система — это всегда набор непростых решений.

Архитектура помогает эти решения принимать осознанно, аргументированно и вовремя.

Маленькая система — 4 компонента, 10 нод — стала таковой благодаря тому, что эти решения принятли по понятной карте и прозрачно для обеих сторон. 

  • Петабайт? Не факт.

Система, которую интегратор оценивает как «огромную», может оказаться куда проще, если поиграть с ограничениями, приоритетами и здравым смыслом.

Часто в продуктовой разработке либо как интеграторы мы сталкиваемся с системами, которые считаем огромными — это же высокоскоростные камеры, 8MB один кадр, это 6400 кадров! Это наверняка много! А когда мы проходим весь этот путь, не факт, что в конечном итоге это будет петабайт — вполне себе может быть и 300 терабайт. Даже меньше! По сути, начав управлять костами разработки и железа, можно найти баланс, избежав перекоса в какую-то из сторон. 

  • Open source + low-code — это не «дёшево», а эффективно.

Бизнес видит результат, разработчики двигают квадратики, бюджет — под контролем. Но: без архитектурной зрелости это превращается в хаос.

Так как доклад у нас про готовые инструменты, хочу отдельно акцентировать внимание, что open source и low-code — это не всегда дёшево, но безусловно эффективно.

Когда мы выбираем low-code решения, то показываем бизнесу доступно как мы это всё разрабатываем. Мы выбрали Apache NiFi в том числе потому, что бизнес мог видеть то, как разработчик двигая квадратики получает сложные пайплайны. Для них это было понятно, они способны были это обработать.

Но используя low-code или open-source без понятной архитектуры мы получаем хаос, причём быстро. Это стоит учитывать и влезать в эту историю только после того, как вы всё спроектировали.

  • Импортозамещение — не приговор.

Даже в условиях запретов, ГОСТов и ограничений можно принимать смелые архитектурные решения, которые облегчают жизнь всей команде.

«Импортозамещение» звучит всегда страшно, но играя с нефункциональными требованиями можно обходить часть ГОСТов и ФЗ. Например, Apache NiFi напрямую в реестре на тот момент не находился, но есть аналоги, построенные на Apache NiFi. Никто не мешает купить лицензию, взять аналог, который уже построен на этой технологии и использовать её при помощи документации вендора и open source.

Бонус для самых внимательных

Я подготовил небольшой чек-лист:

Так я подхожу к решению сложных задач. Этот чек-лист составлен сознательно не по порядку, потому что кому-то легче посмотреть сначала на контекст системы, потом прикинуть логическую часть, затем — посмотреть нефункциональные требования. А кому-то, напротив, проще сначала понять объёмы, время, трафик, SLA, и только потом лезть в логику. Его можно использовать как в обратную сторону, так и дёргать из середины. Это, скорее, некий mind map.

Подробнее о моём пути вы можете ознакомиться в тг-канале, где публикуются «записки ударника труда» программиста с опытом 7+ лет.

Также рекомендую прочитать статью об архитектурном комитете — она в двух частях. В первой рассказываю про Definition of Ready (DoR) и Definition of Done (DoD), а также про статусную модель. Во второй — про приемку архитектурных документов и ADR (Architectural Decision Record).

Скрытый текст

Если вы хотите узнать больше о технологиях, позволяющих одновременно обслуживать многие тысячи и миллионы пользователей, не пропустите крупнейшую профессиональную конференцию для разработчиков высоконагруженных систем HighLoad++ 2025! Вас ждёт более 140 докладов, восемь мастер-классов и возможность обменяться опытом почти с более 3 тыс. специалистов.

Комментарии (0)