Managed workflows. Путешествие в мир машин

Привет, меня зовут Виталий Корж, я Data Miner в Luxoft Ukraine. Мне часто приходится заниматься поиском, сбором и обработкой данных для дальнейшего использования в различных проектах. В последнее время спрос на инструменты обработки данных вырос, а с проявлением интереса от могучего ритейлера в этой сфере стоит рассмотреть некоторые возможности и особенности проектирования таких систем.

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

Восстание машин

Весь наш код пронизан сценариями, для них существует целое семейство шаблонов, но бывает так, что задача не может быть выполнена в одной транзакции. Периодически возникает необходимость произвести дополнительные операции после выполнения какого-то действия. В таких случаях на помощь приходят Managed Workflows (Finite State Machine).

Они пришли помочь, но не все это оценили

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

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

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

Такие системы уже используются как полноценные решения в цепочке производства (яркий пример NIFI). Самыми распространенными гибкими, но в то же время требовательными в работе, являются разного рода самописные системы, где последовательность действий определяется на программном уровне.

Такие системы могут иметь все атрибуты вышеописанных решений, но дают полную свободу действий (Camunda, Cadence, Conductor, многие другие).

Различные программы борются за внимание

Как обуздать систему

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

Список требований к такой системе будет следующим:

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

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

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

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

Рассмотрим каждую из характеристик в отдельности.

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

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

Короче! Если сервисы уже написаны или нет желания их править — берем оркестратор, иначе сервер-клиент.

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

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

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

Ну и че? Стороннее решение синхронным быть не может, такое мы и сами напишем.

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

Примером такой интеграции может служить нотификация о просроченных тасках. Также непрерывность характерна для различного рода ETL-процессов, где данные должны быть преобразованы из одного состояния в другое. Наличие прерываний в схеме возможно при ожидании сторонних действий.

Так шо тут? У вас есть пользователи — забудьте о непрерывности.

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

А попроще? Нужно через год быть уверенным в успешном повторении сценария, храните схемы.

Ресурсоемкость системы можно игнорировать в том случае, когда затраты на ее содержание ничтожно малы в сравнении с основным продуктом. Масштабность такой системы должна быть соразмерна вашей системе и не требовать внедрения дополнительных технологий для своей эксплуатации. Если необходимо по крону собирать отчеты и отправлять уведомления всем заинтересованным, необязательно создавать систему с ZooKeeper и Cassandra.

Какая емкость? Цените свое время, сделать лучше еще успеете.

Все такие похожие, но где-то скрывается бриллиант

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

Не техникой единой

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

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

Доступнее! Не получилось запустить в течение часа — не трать время.

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

Че? Система и схема тасок как конструктор у нее.

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

А еще короче? С сахаром главное не переборщить.

Сколько проектов, столько и воркфлоу

В качестве примера опишем некоторые системы в одно предложение. AWS Step Functions: отлично документированный одноразовый асинхронный оркестратор с поддержкой прерываний, с простым синтаксисом.

Netflix Conductor: обманчиво простая многоразовая асинхронная распределенная система.

Почти любой ETL: гибкий и документированный синхронный оркестратор, требующий терпения в эксплуатации.

Выводы

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

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

👍НравитсяПонравилось1
В избранноеВ избранном1
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Виталий, спасибо за интересную статью! В нашей компании тоже в какой-то момент возникло желание оптимизировать рутинную задачу, связанную с синхронизацией данных между разными системами. Самый первый юз кейс был довольно простой: нам нужно было засетапить автоматическую интеграцию между Airtable и Google Sheets. Решением данной проблемы послужило создание своего продукта Coupler.io В работе, мы также используем Zapier для автоматизации передачи данных по триггеру. Основной юз кейс здесь: автоматизация процессов найма и онбординга сотрудников. Еще в какой-то момент мы экспериментировали со Stitch Data и использовали ее для сбора данных в Google BigQuery (а сейчас эту задачу уже покрывает собственный продукт).

Виталий, спасибо, крутая статья!

Спасибо за статью — тема интересная.
Но было бы полезнее/интереснее взять какой-либо микро конкретный/выдуманный кейс и реализовать его с использованием различных инструментов и предложенным набором рекомендаций (крупными мазками) — тут и сравнение самих инструментов было бы (что довольно актуально в виду далеко не нулевой стоимости изучения каждого из них) и более явно можно отразить полезность самих рекомендация — они ведь не на ровном месте появились — скорее всего за каждым из них есть какая-либо история или личная боль с проекта :)

Спасибо, учту.
Сами рекомендации скорее позволяют оценить любое решение со стороны управляемости. Распределенная система на кафке, и елк в качестве графического интерфейса, вполне подходит под определение managed workflow. Собственно по этому формулировки не были привязаны к определенным решениям

Подписаться на комментарии