Yuriy Gavrilov

Welcome to my personal place for love, peace and happiness 🤖

Bar is sooooooooo high – Platform Takes The Pain

Часть 1: “Bar is sooooooooo high” – https://nekrolm.github.io/blog.html

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

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

  • `Bar is sooooooooo high`: “Планка неимоверно высока”. Означает, что требования для повышения (промоушена) настолько завышены, что достичь их практически невозможно, даже если ты уже выполняешь работу на следующем уровне. Это создает ощущение бега на месте.
  • `RSU (Restricted Stock Units)`: Акции компании, которые выдаются сотруднику, но он получает их не сразу, а по частям в течение нескольких лет. Это способ удержания ценных кадров. Автор отказался от ~£100k, не дождавшись очередного получения акций.
  • `FAANG`: Акроним для гигантов технологической индустрии: Facebook (теперь Meta), Amazon, Apple, Netflix, Google. Символ престижной и высокооплачиваемой работы в IT.
  • `Return-to-office`: “Возвращение в офис”. Политика компании, обязывающая сотрудников работать из офиса определенное количество дней в неделю.
  • `Oncall`: “Дежурство”. Период, когда инженер должен быть доступен 24/7 для решения экстренных проблем с продакшн-системами. В статье это источник огромного стресса из-за сложности системы и широкого круга обязанностей.
  • `Leadership Principles`: “Принципы лидерства”. 16 “заповедей” Amazon, которые должны направлять поведение сотрудников. Автор иронично использует их, чтобы показать, как в реальности они превращаются в инструменты бюрократии и давления.
  • `Receive shouldertaps`: “Получать ‘похлопывания по плечу’”. Метафора, означающая постоянные отвлечения, прерывания и запросы от коллег и менеджеров, которые мешают сосредоточиться на основной задаче.
  • `Let’s keep rollout aside`: “Давайте пока не будем думать о раскатке”. Фраза менеджера, которая говорит о том, что процесс релиза настолько сложный, долгий (от месяца до года) и рискованный, что его даже не пытаются планировать и оценивать.
  • `Customer Obsession`: “Одержимость клиентом”. Один из принципов лидерства. В статье показана его гипертрофированная форма, когда нужно реагировать даже на падение одного запроса из миллиона.
  • `Correction-of-errors document (COE)`: Документ с разбором ошибок. Его написание и защита перед высшим руководством — крайне неприятная процедура после любого сбоя.
  • `Bar Rising`: “Поднятие планки”. Процесс ревью и “прожарки” на митингах, где любая идея подвергается шквалу критики и сомнений, что ведет к выработке синдрома самозванца. пс: у кого-то “паяльники” рабочий инструмент, а у матерых компаний “градусники для мяса”. 🤣 Что поделать, идут дальше, контролируют степень “прожарки” в виде ежедневных опросов, что бы не подгорало.
  • `Ownership`, `Operational Excellence`: Другие принципы лидерства, которые на практике означают, что дежурный инженер несет полную ответственность за гигантскую и запутанную систему.
  • `In pain`: “Страдает”. Эмоционально окрашенный термин для описания клиента с проблемой, используемый для создания срочности.
  • `Disagree and Commute`: “Не согласен, но езди в офис”. Ироничная переделка принципа `Disagree and Commit` (“Не согласен, но поддерживай решение”). Отражает отношение к принудительному возвращению в офис.
  • `GenAI`: Генеративный Искусственный Интеллект. Автор описывает неадекватную истерию вокруг этой темы в компании.
  • `Bellow benchmarks`: “Ниже эталонных показателей”. Результат анонимных опросов удовлетворенности, который показывает, что команда недовольна, и приводит к игре в “мафию” — поиску виноватых.

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

Футбол кстати вовлекает 40% населения, а количество зрителей финала чемпионата может достигать 1,5 млрд. человек.

Стоимость бренда UFC – 4 млрд$, но цифра уже устарела, 11 дек. 2024 г. — $10 миллиардов, — Глава UFC оценил, а в августе этого года Paramount приобрела права на трансляцию UFC за $7,7 млрд. Сейчас оценка где-то 11млрд. За один просмотр выручка c трансляции одного боя может достигать 180$ млн.

А вот Люк как запомнился, “Он говорил на языке страсти, а не KPI”

Ну вы все уже знаете. 81 сервис пострадал, +800 компаний где-то, даже медиум лежал.

Облака, белогривые лошадки,
Облака, что вы мчитесь без оглядки
Не смотрите вы пожалуйста свысока,
А по небу прокатите нас облака... Трям! Здравствуйте!»))


Рецепт выгорания от Amazon или почему “планка так высока”

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

Причина кроется в самой культуре, парадоксальным образом описанной через знаменитые `Leadership Principles` Amazon. Принцип `Insist on Highest Standards` (“Настаивайте на высочайших стандартах”) на практике превращается в бюрократическую “прожарку” (`Bar Rising`), где любая инициатива тонет в бесконечных согласованиях и документах. Чтобы выпустить даже небольшое изменение, нужно “просмотреть все варианты будущего”, как Доктор Стрэндж, и защитить свое решение перед армией сомневающихся.

Вершиной этой культуры становится процесс релиза. Фраза менеджера `Let’s keep rollout aside` говорит сама за себя: раскатка изменений в продукте, через который проходит 30% интернет-трафика, — это настолько болезненный и непредсказуемый процесс, что его предпочитают даже не обсуждать. Проект, сделанный за 2 недели, может добираться до пользователей полтора года. Как пишет автор, это лучший рецепт для выгорания: “Заставьте программистов писать код, не дайте им увидеть результат и при этом дергайте их в разные стороны”.

Эти “подергивания” (`shouldertaps`) — еще один гвоздь в крышку гроба мотивации. Дежурства (`oncall`) превращают инженера в универсального солдата, который должен ориентироваться в сотнях дашбордов, десятках видов логов и нести `Ownership` за все, что происходит. При этом `Customer Obsession` доходит до абсурда: приходится разбираться с падением одного запроса из миллиона, потому что клиент `in pain`.

На фоне этого — постоянные увольнения, принудительное “возвращение в офис” (`Disagree and Commute`) и неадекватная `GenAI`-истерия. В итоге “планка” (`bar is so high`) для карьерного роста оказывается не стимулом, а стеной, о которую разбиваются амбиции. Это история о том, как система, созданная для минимизации рисков в огромном масштабе, начинает пожирать человеческий ресурс, превращая талантливых инженеров в выгоревших статистов.


Стихотворение в стиле АЙ да Пушкина :)  🤖

Три года в царстве AWS,
Где каждый день — суровый стресс.
Прощай, гигант, твой дом высок,
Но дух мой страждет и продрог.

Чтоб строчку кода в мир пустить,
Трактат надобно сочинить.
На том совете господа
Тебя осудят без труда.

“А точно ль цель сия верна?
Вся ль сложность вами учтена?”
Идёт полгода, год второй,
А код твой спит, еще не в строй.

Дежурства мрак, клиент “in pain”,
И кашель рвёт грудину мне.
И планка та, что так горда,
Лишь множит горе и года.

Оставлю акций бренный звон,
Покину сей хрустальный трон.
Свободным быть — вот мой удел,
Прощай, Amazon, я улетел.


Часть 2: О статье про Spotify (“Platform Takes The Pain”)

Эта статья, основанная на подкасте corecursive.com, рассказывает о внутренней трансформации Spotify на пути от хаотичного стартапа в стадии гиперроста до зрелой технологической компании. Это история о том, как им удалось навести порядок, не убив свою знаменитую культуру автономии.

Суть и смысл статьи

Основная идея — Spotify столкнулся с проблемой масштабирования. Их культура полной автономии команд, где каждая сама отвечала за свой конвейер сборки и доставки (CI/CD), привела к хаосу: более 300 команд использовали 200+ разных, небезопасных версий CI-системы Jenkins. Перед выходом на IPO аудиторы указали на это как на серьезный риск.

Компании нужно было за 6 месяцев стандартизировать CI, но как это сделать, не нарушив главный принцип — автономию инженеров, которые не хотели, чтобы им что-то навязывали “сверху”?

Решением стала смена парадигмы в работе платформенных команд под лозунгом `Platform Takes The Pain` (“Платформа забирает боль на себя”).

Устройство, культура и особенности Spotify

  1. Культура “старого” Spotify (до трансформации):
    • Хорошо:
      • Полная автономия: Команды (`squads`) были абсолютно независимы, что давало им чувство сопричастности и ускоряло принятие решений в малом масштабе.
      • Сильная идентичность: У каждой команды была своя “комната” (`squad room`), оформленная в уникальном стиле, что создавало сильную командную связь.
      • Скорость и гениальные инженеры: В компании были “звёзды” (“employee number 10”), которые могли писать код день и ночь и знали всё об инфраструктуре.
    • Не очень:
      • Хаос и фрагментация: Более 200 CI-систем — яркий пример. Это приводило к дублированию работы и уязвимостям.
      • “Rumor Driven Development” (“Разработка, основанная на слухах”): Чтобы что-то узнать, нужно было “похлопать по плечу” нужного человека. Не было единого источника информации, что замедляло новичков и приводило к созданию костылей.
      • Проблемы с онбордингом: Новичку требовалось более 60 дней, чтобы сделать свои первые 10 Pull Request.
      • Хрупкость: Если ключевой инженер уходил в отпуск, система могла остаться без поддержки.
  1. Трансформация и новая культура:
    • Мантра `Platform Takes the Pain`: Платформенные команды перестали быть просто создателями инструментов “в стол”. Они стали сервис-провайдером для внутренних клиентов — других команд разработчиков. Их новой задачей стало не просто создать инструмент, а взять на себя ответственность за его внедрение (`adoption`). Они приходили в команды и помогали им мигрировать, забирая на себя самую нудную и сложную работу.
    • `Backstage` — решение проблемы “слухов”: Чтобы победить `Rumor Driven Development`, Spotify создали единый портал для разработчиков — `Backstage` engineering.atspotify.com.
      • Устройство: Это центральный каталог, где можно найти информацию о любом сервисе, его владельце, документации, API и дежурном инженере.
      • Главная особенность: `Backstage` построен на плагинах. Это значит, что центральная команда не стала “бутылочным горлышком”. Любая команда может написать свой плагин для `Backstage`, чтобы добавить нужную ей функциональность. Это гениальное решение, которое централизует информацию, но децентрализует владение и развитие платформы.
    • Переосмысление автономии: В Spotify поняли, что автономия ради автономии бессмысленна. Настоящая цель автономии — влияние (`impact`). Если команда автономна, но изолирована и ее работа не приносит пользы, это плохая автономия. Новые стандарты и инструменты вроде `Backstage` не убили автономию, а, наоборот, дали командам больше влияния, убрав рутину и упростив взаимодействие.

*На Backstage кстати можно строить порталы IDP https://internaldeveloperplatform.org/what-is-an-internal-developer-platform/

Чем Spotify отличается от других (например, от Amazon из первой статьи)?

Аспект Amazon (согласно статье) Spotify (согласно статье)
Процесс Процесс — это цель. Бюрократия и избегание рисков приводят к параличу. Релизы длятся годами. Процесс — это средство. Цель — скорость итераций. Узкие места (bottlenecks) активно устраняются.
Автономия Индивидуальная ответственность (`Ownership`), которая часто превращается в поиск виноватого. Командная автономия, нацеленная на результат (`impact`). Баланс между свободой и общими стандартами.
Платформа Не описано, но похоже на набор сложных инструментов, за которые ты сам несешь ответственность. Платформа как сервис (`Platform takes the pain`). Платформенные команды — помощники, а не надзиратели.
Культура Top-down (сверху-вниз). Жесткие принципы, которые могут использоваться для давления. Страх ошибки. Bottom-up (снизу-вверх). Культура эволюционировала в ответ на реальные проблемы. Поощрение экспериментов и “быстрых провалов”.
Информация Скрыта в тысячах репозиториев и устаревших вики. Огромный контекст, который невозможно удержать. Централизована и доступна через `Backstage`. Прозрачность — один из ключевых принципов.

Итоги

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

Основные выводы:

  1. Платформа должна служить разработчикам, а не диктовать им условия. Модель `Platform Takes The Pain` — это то, чему стоит поучиться многим компаниям.
  2. Централизуйте информацию, а не контроль. Инструмент вроде `Backstage` с плагинной архитектурой — мощное решение для сохранения скорости и автономии в большом масштабе.
  3. Культура не высечена в камне. Она должна адаптироваться к размеру и задачам компании. Spotify смогли переосмыслить “автономию”, привязав её к реальному влиянию на продукт.

Для компаний, стремящихся к росту, опыт Spotify

sciencedirect.com — это дорожная карта по построению эффективной и при этом человечной инженерной организации. А для инженеров, выбирающих место работы, это маркер здоровой культуры: ищите компании, которые борются с трением, а не создают его. Как говорится, если в компании есть свой `Backstage` — это хороший знак. Если же там “let’s keep rollout aside” — возможно, стоит бежать.

Если коротко – оригинал по ссылке выше

В статье анализируется организационная модель Spotify, которая позволяет предоставлять высокую степень автономии сотням команд разработчиков (называемых «сквадами», или `squads`) и при этом эффективно координировать их работу в масштабах всей компании.

Авторы утверждают, что масштабируемая автономия в Spotify — это не анархия. Это тщательно продуманная система, в которой свобода команд уравновешивается механизмами, обеспечивающими согласованность действий и общую ответственность. Сквады, задуманные как «мини-стартапы», имеют право самостоятельно принимать большинство решений, касающихся их работы: как разрабатывать, какие процессы использовать, как отслеживать свой прогресс.

Однако эта свобода существует в рамках так называемых «благоприятствующих ограничений» (`enabling constraints`). Эти ограничения — не приказы сверху, а скорее общие правила и инструменты, которые помогают командам работать слаженно, не создавая хаоса. Исследование основано на ретроспективах с командами, интервью с менеджерами и анализе внутренних данных Spotify.

Основные рекомендации и стратегии, применяемые в Spotify

Для достижения баланса между автономией и согласованностью Spotify использует несколько ключевых стратегий:

  1. Выравнивание (Alignment) вместо контроля: Вместо того чтобы указывать командам, *что* и *как* делать, компания создает условия для естественной синхронизации.
    • `TechRadar` (Технологический радар): Это централизованный, но коллективно управляемый список одобренных технологий, языков программирования и фреймворков. Команды не могут использовать абсолютно любую технологию, что упрощает поддержку, обмен инженерами и совместную работу над кодом.
    • Запросы на комментарии (`RFCs – Requests for Comments`): Для крупных изменений, затрагивающих несколько команд, используется формальный процесс RFC. Это позволяет собрать обратную связь и достичь консенсуса до начала реализации.
    • «Золотые пути» (`Golden Paths`): Это готовые шаблоны и руководства для выполнения стандартных задач (например, создание нового микросервиса). Это снижает когнитивную нагрузку на инженеров и обеспечивает единообразие.
  1. Управление общей кодовой базой:
    • «Слабое владение кодом» (`Weak Code Ownership`): У каждого компонента кода есть команда-владелец, но любая другая команда может предлагать изменения через пул-реквесты (`Pull Requests`). Команда-владелец обязана рассмотреть эти изменения. Это предотвращает возникновение «узких мест» и поощряет коллективную ответственность за продукт.
    • Самостоятельное управление зависимостями: Команды могут договариваться между собой и передавать владение кодовыми репозиториями, чтобы уменьшить зависимости и ускорить свою работу.
  1. Сетевые структуры и обмен знаниями: Компания активно развивает горизонтальные связи, минуя формальную иерархию.
    • Гильдии (`Guilds`): Это добровольные сообщества по интересам (например, гильдия веб-разработчиков или гильдия по качеству). Они служат для обмена знаниями, выработки лучших практик и решения общих проблем.
    • Культура взаимопомощи и внутренние инструменты: Использование корпоративного Slack и внутреннего аналога Stack Overflow поощряет открытый обмен информацией. Репутация инженера или команды отчасти зависит от их готовности помогать другим.
    • «Встраивание» (`Embedding`): Практика временного (до трех месяцев) «одалживания» инженеров между командами. Это помогает быстро передавать экспертизу, решать проблемы с зависимостями и укреплять социальные связи.

Что выходит?

  • Масштабируемая автономия возможна и эффективна. Модель Spotify доказывает, что можно предоставить командам значительную свободу даже в очень крупной организации. Ключ к успеху — в способности команд к самоорганизации, сотрудничеству и коллективному принятию решений.
  • Автономия требует ответственности и согласованности. Свобода не работает без «благоприятствующих ограничений». Именно эти рамки позволяют всей системе оставаться управляемой и двигаться в одном направлении.
  • Основные барьеры для автономии не всегда связаны с менеджментом. Главными препятствиями являются технические и организационные зависимости между командами, недостаточная зрелость самих команд (неумение управлять своими процессами) и нехватка нужных компетенций.
  • Существует «цепь автономии». Производительность всей системы ограничена ее самым медленным и наименее автономным звеном. Проблемы одной команды быстро становятся проблемами для многих других, которые от нее зависят.
  • Главный вызов — поддержание модели при росте. По мере роста компании поддерживать культуру автономии и эффективные горизонтальные связи становится все сложнее. Это требует постоянных усилий и адаптации существующих практик.

Построение надежных ML-систем и технический долг

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

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

Часть 1. Карта жизненного цикла ML-проекта

Любой ML-проект — это не просто обучение модели, а сложный, итеративный процесс. Рассмотрим его типичный жизненный цикл, разделив на две основные фазы: Исследования и Эксплуатация.

Из книги масштабируемые данные

Фаза 1: Исследования (Research)

Это итеративный этап проверки гипотез. Главная цель — доказать (или опровергнуть), что с помощью ML можно решить поставленную бизнес-задачу с приемлемым качеством.

  1. Запуск проекта:
    • Задачи:** Четкое определение бизнес-проблемы и формулировка ML-гипотезы («Сможем ли мы предсказывать Y с помощью данных X с точностью N?»). На этом этапе важно задать фундаментальный вопрос: а нужно ли здесь вообще машинное обучение? Создается техническая инфраструктура: репозиторий в Git, проект в системе CI/CD (например, Jenkins, GitLab CI).
    • Участники:** Бизнес-заказчики, продуктовые менеджеры, аналитики, специалисты по Data Science.
  1. Проектирование данных:
    • Задачи:** Поиск, сбор и интеграция данных из различных источников в единое хранилище («озеро данных»). Затем данные исследуются на предмет полноты, аномалий и качества, после чего происходит их очистка, трансформация и регистрация в качестве «очищенных» наборов данных.
    • Участники:** Инженеры данных (Data Engineers), команда DWH, специалисты по Data Science.
  1. Экспериментирование:
    • Задачи:** Это сердце работы Data Scientist. Здесь происходит генерация признаков (`feature engineering`), подбор архитектуры модели, ее обучение, валидация и оценка. Критически важными шагами являются версионирование данных и кода, а также фиксация всех результатов и метрик для обеспечения воспроизводимости.
    • Участники:** Специалисты по Data Science (ML/DS).

Эта фаза завершается решением: если эксперименты успешны, проект переходит в фазу эксплуатации. Если нет — он либо отправляется на новый виток исследований, либо закрывается.

Фаза 2: Эксплуатация (Operations / MLOps)

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

  1. Ввод в эксплуатацию:
    • Задачи: Код, написанный для экспериментов, часто требует серьезного рефакторинга и оптимизации для производственной среды. Строится автоматизированный конвейер (pipeline), который выполняет все шаги: от получения свежих данных до выгрузки предсказаний. Этот процесс должен быть не только автоматизированным, но и устойчивым к сбоям, что является ключевым принципом как MLOps, так и классической инженерии надежности Reliability Engineering arxiv.org.
    • Участники: ML-инженеры, DevOps-инженеры, инженеры данных.
  1. Мониторинг:
    • Задачи: После развертывания работа не заканчивается. Необходимо постоянно отслеживать как технические, так и качественные показатели модели: стабильность входных данных, качество предсказаний (точность, полнота), а также бизнес-метрики. Для оценки реального влияния на продукт проводятся А/В-тесты.
    • Участники: ML-инженеры, SRE (Site Reliability Engineers), аналитики, продуктовые менеджеры.

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

Часть 2. «Скрытый технический долг в системах машинного обучения»

В 2015 году исследователи из Google опубликовали знаковую работу «Hidden Technical Debt in Machine Learning Systems». Они показали, что в ML-системах технический долг накапливается быстрее и опаснее, чем в традиционном ПО.

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

Ключевые источники технического долга в ML:

  1. Эрозия границ и связанность (Entanglement): В ML практически невозможно изолировать компоненты из-за принципа CACE («Changing Anything Changes Everything» — «Изменение чего угодно меняет всё»).
    • Изменение одного признака влияет на важность всех остальных.
    • Добавление нового признака `x_n+1` может полностью изменить веса старых `x_1...x_n`.
  1. Зависимости от данных (Data Dependencies): Эти зависимости коварнее зависимостей от кода, так как их сложнее отследить статически.
    • Нестабильные данные: Использование данных из другой ML-системы, которая может обновляться без вашего ведома — это бомба замедленного действия. «Улучшение» в той системе может сломать вашу.
    • Недоиспользуемые данные: Со временем признаки могут становиться ненужными (Legacy Features), добавляться «пачкой» ради мнимого прироста метрик (Bundled Features) или дублировать друг друга (Correlated Features). Они не приносят пользы, но увеличивают сложность и уязвимость системы.
  1. Антипаттерны проектирования:
    • Код-клей (Glue Code): Огромное количество кода пишется для «склеивания» данных с универсальной ML-библиотекой (например, `scikit-learn`, `TensorFlow`). Авторы утверждают, что в зрелой системе ML-код может составлять всего 5%, а остальное — «клей».
    • Джунгли конвейеров (Pipeline Jungles): Системы подготовки данных часто разрастаются органически, превращаясь в запутанные «джунгли» из скриптов, которые невозможно тестировать, отлаживать и развивать.
    • Мертвые пути экспериментов: В коде остаются ветки `if/else` от прошлых экспериментов, которые усложняют тестирование и создают риск неожиданного поведения.
  1. Петли обратной связи (Feedback Loops): Модель в реальном мире влияет на среду, из которой она же и получает данные для будущего обучения. Это может привести к сужению разнообразия и деградации модели, когда она начинает усиливать свои собственные прошлые решения.
  1. Долг конфигурации (Configuration Debt): Конфигурация ML-систем (какие признаки использовать, параметры алгоритма, пороги) часто занимает больше строк, чем сам код. Ею сложно управлять, ее редко тестируют, а ошибки в ней могут приводить к катастрофическим последствиям.

Часть 3. Практические выводы

Схема жизненного цикла из Части 1 показывает, ЧТО и КОГДА нужно делать. Статья о техническом долге из Части 2 объясняет, ПОЧЕМУ и КАК это нужно делать правильно, чтобы система не развалилась через полгода.

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

  • Блок Экспериментирование — это фабрика по производству `кода-клея` и `недоиспользуемых признаков`. Погоня за сотыми долями процента в метрике качества часто приводит к огромному усложнению системы.
  • Блок Ввод в эксплуатацию без рефакторинга и целостного проектирования порождает `джунгли конвейеров`.
  • Блок Мониторинг — главный инструмент для обнаружения последствий технического долга: смещения данных (Data Drift) и деградации модели (Model Drift).
Рекомендации по созданию надежных ML-систем

Чтобы построить устойчивую ML-систему, необходимо с самого начала применять инженерную дисциплину.

  1. Целостный подход к надежности. ML-система — это не только модель. Это данные, признаки, код, конвейеры и мониторинг. Цель — не просто высокая точность, а построение надежной и заслуживающей доверия системы ieeexplore.ieee.org.
  1. Версионирование всего. Для борьбы с хаосом необходимо версионировать всё: данные, код, параметры экспериментов и итоговые модели. Это единственный способ обеспечить воспроизводимость и возможность отката.
  1. Автоматизация (MLOps). Ручные шаги — источник ошибок. Все процессы, от сборки данных до развертывания модели, должны быть автоматизированы. Тестирование должно включать не только код, но и данные (проверки на соответствие схеме, распределению), а также качество самой модели.
  1. Проактивный мониторинг. Настройте алерты на аномалии во входных данных (data drift), падение качества предсказаний (model drift) и нарушение ключевых бизнес-метрик. Это ваш радар для обнаружения скрытого технического долга в реальном времени.
  1. Проектирование с учетом отказоустойчивости. Система должна быть спроектирована так, чтобы изящно справляться с частичными сбоями: например, иметь логику-запасной вариант (fallback), если источник данных недоступен, или временно отключать модель, если ее предсказания становятся неадекватными medium.com.
  1. Кросс-функциональные команды и культура. Жесткое разделение ролей «исследователь» (Data Scientist) и «инженер» (ML Engineer) — корень многих проблем. Наиболее успешные команды — это гибридные группы, где инженеры и исследователи работают вместе. Такая культура ценит не только прирост точности, но и упрощение системы, удаление лишних признаков и снижение общей сложности.

Заключение

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


Ниже представлен перевод и краткий пересказ ключевых идей научной статьи «Скрытый технический долг в системах машинного обучения» от D. Sculley и других исследователей из Google. Пояснения к терминам и концепциям добавлены в формате ``.

Оригинал тут: http://a.gavrilov.info/data/posts/ml-Paper.pdf


Скрытый технический долг в системах машинного обучения

Аннотация

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

1. Введение

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

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

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

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

2. Размывание границ из-за сложности моделей

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

  • Связанность (Entanglement). МО-системы смешивают сигналы, делая изоляцию улучшений невозможной. Это принцип CACE (Changing Anything Changes Everything — «Изменение чего угодно меняет всё»). Изменение распределения одного признака (x₁) может изменить важность или веса всех остальных признаков. Добавление или удаление признаков имеет тот же эффект. Улучшение одной модели в ансамбле может ухудшить общую точность системы, если ошибки станут более коррелированными.
  • Каскады исправлений (Correction Cascades). Часто возникает соблазн исправить проблему A’, которая немного отличается от уже решенной проблемы A, создав новую модель `m’` поверх существующей модели `mA`. Эта новая модель `m’` учится вносить небольшую поправку. Однако это создаёт новую зависимость от `mA`, что делает будущий анализ улучшений `mA` значительно дороже. Каскады таких исправлений могут привести к тупиковой ситуации, когда улучшение любого отдельного компонента ухудшает общую производительность системы.
  • Необъявленные потребители (Undeclared Consumers). Часто предсказания МО-модели становятся общедоступными (например, через логи). Другие системы могут начать тайно использовать эти данные в качестве входных. В классической инженерии это называют долгом видимости . Такие необъявленные потребители создают скрытую жёсткую связь. Любые изменения в исходной модели, даже улучшения, могут негативно и непредсказуемо повлиять на эти системы-потребители.

3. Зависимости от данных стоят дороже зависимостей от кода

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

  • Нестабильные зависимости от данных. Удобно использовать в качестве признаков данные из других систем. Однако если эти входные сигналы нестабильны (например, сами являются выходом другой МО-модели, которая со временем обновляется), они могут меняться. Даже «улучшения» входного сигнала могут иметь разрушительные последствия для потребляющей его системы. Распространённая стратегия смягчения — создание версионных, «замороженных» копий таких данных.
  • Недостаточно используемые зависимости от данных. Это входные сигналы, которые дают очень небольшой прирост производительности, но делают систему излишне уязвимой к изменениям. Они могут появиться несколькими путями:
    • Устаревшие признаки (Legacy Features): Признак добавляется на ранней стадии, со временем новые признаки делают его избыточным, но его не удаляют.
    • Пакетные признаки (Bundled Features): Группа признаков добавляется вместе, потому что «в пакете» они показали пользу, хотя некоторые из них по отдельности бесполезны.
    • ε-признаки : Признаки, которые добавляют ради крошечного прироста точности, но при этом значительно усложняют систему.
    • Коррелированные признаки (Correlated Features): Когда два признака сильно коррелируют, модель может ошибочно отдать предпочтение не причинно-следственному, а зависимому, что делает систему хрупкой, если в будущем эта корреляция изменится.


Рисунок 1: Лишь малая часть реальных МО-систем состоит из кода МО (маленький чёрный квадрат в центре).

Необходимая окружающая инфраструктура огромна и сложна.

  • `ML Code` — Код МО
  • `Configuration` — Конфигурация
  • `Data Collection` — Сбор данных
  • `Feature Extraction` — Извлечение признаков
  • `Data Verification` — Верификация данных
  • `Machine Resource Management` — Управление ресурсами
  • `Analysis Tools` — Инструменты анализа
  • `Process Management Tools` — Инструменты управления процессами
  • `Serving Infrastructure` — Инфраструктура для развёртывания
  • `Monitoring` — Мониторинг

4. Петли обратной связи

Ключевая особенность работающих МО-систем — они часто начинают влиять на собственное поведение.

  • Прямые петли обратной связи. Модель напрямую влияет на выбор данных для своего будущего обучения. Например, система рекомендаций показывает пользователю определённые товары; если пользователь кликает на них, эти клики используются для дообучения модели, что закрепляет её текущее поведение.
  • Скрытые петли обратной связи. Две отдельные системы косвенно влияют друг на друга через реальный мир. Пример: одна система выбирает товары для показа на веб-странице, а другая — связанные с ними отзывы. Улучшение одной системы (например, показ более релевантных товаров) приведёт к изменению поведения пользователей (больше кликов), что, в свою очередь, повлияет на вторую систему (какие отзывы показывать).

5. Антипаттерны МО-систем

Для академического сообщества может быть удивительно, что в реальных МО-системах лишь малая часть кода (см. Рисунок 1) отвечает непосредственно за обучение или предсказание. Остальное — это инфраструктурная «обвязка».

  • «Код-клей» (Glue Code) . Системный дизайн, при котором пишется огромное количество вспомогательного кода для передачи данных в универсальные МО-пакеты и из них. Этот код «приклеивает» систему к особенностям конкретного пакета, делая переход на альтернативы крайне дорогим. Иногда дешевле создать чистое нативное решение, чем использовать универсальный пакет, если 95% системы — это «код-клей».

  • «Джунгли конвейеров» (Pipeline Jungles). Особый случай «кода-клея», часто возникающий при подготовке данных. Системы превращаются в «джунгли» из скриптов для парсинга, объединения данных и сэмплирования, которыми сложно управлять и тестировать.
  • Мёртвые ветки экспериментального кода (Dead Experimental Codepaths). Часто для экспериментов в основной код добавляются временные условные ветки. Со временем они накапливаются, усложняя поддержку обратной совместимости и тестирование. Знаменитый пример — система Knight Capital, потерявшая $465 млн за 45 минут из-за непредвиденного поведения устаревшего экспериментального кода.
  • Долг абстракции (Abstraction Debt). В МО не хватает сильных, общепринятых абстракций, подобных реляционной базе данных в мире СУБД. Это размывает границы между компонентами системы.

Распространённые «запахи» кода в МО

  • «Запах» простых типов данных (Plain-Old-Data Type Smell): Использование обычных `float` или `int` вместо более насыщенных типов. Например, параметр модели должен «знать», является он порогом принятия решения или множителем.
  • «Запах» многоязычности (Multiple-Language Smell): Использование нескольких языков программирования в одной системе усложняет тестирование и передачу ответственности.
  • «Запах» прототипа (Prototype Smell): Постоянное использование отдельной среды для прототипирования может указывать на то, что основная система слишком неповоротлива и сложна для изменений. Существует опасность, что под давлением сроков прототип будет запущен в продакшен.

6. Долг конфигурации

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

Принципы хорошей системы конфигурации:

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

7. Работа с изменениями во внешнем мире

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

  • Фиксированные пороги в динамических системах. Часто порог принятия решения (например, для классификации письма как спама) устанавливается вручную. Если модель обновляется на новых данных, этот старый порог может стать недействительным.
  • Мониторинг и тестирование. Необходимо в реальном времени отслеживать поведение системы. Ключевые метрики для мониторинга:
    • Смещение предсказаний (Prediction Bias): Распределение предсказанных меток должно соответствовать распределению реальных меток. Отклонение этого показателя часто указывает на проблемы.
    • Ограничения на действия (Action Limits): В системах, которые выполняют действия в реальном мире (например, делают ставки на аукционе), полезно устанавливать «разумные» лимиты. Срабатывание такого лимита должно вызывать тревогу и требовать ручного вмешательства.
    • Поставщики данных (Up-Stream Producers): Системы, поставляющие данные для МО-модели, должны тщательно отслеживаться и тестироваться. Любые сбои в них должны немедленно передаваться в МО-систему.

8. Другие области долга, связанного с МО

  • Долг тестирования данных (Data Testing Debt). Если данные заменяют код, то данные, как и код, должны тестироваться.
  • Долг воспроизводимости (Reproducibility Debt). Воспроизводить эксперименты в реальных системах сложно из-за рандомизации, недетерминизма параллельных вычислений и взаимодействия с внешним миром.
  • Долг управления процессами (Process Management Debt). В зрелых системах могут работать сотни моделей одновременно. Это порождает проблемы с массовым обновлением конфигураций, управлением ресурсами и т.д.
  • Культурный долг (Cultural Debt). Жёсткая граница между «исследователями МО» и «инженерами» контрпродуктивна. Важно создавать культуру, в которой удаление признаков, снижение сложности и улучшение стабильности ценятся так же высоко, как и повышение точности.

9. Выводы: Измерение и выплата долга

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

Полезные вопросы для оценки долга:

  • Насколько легко протестировать совершенно новый алгоритмический подход в полном масштабе?
  • Каково транзитивное замыкание всех зависимостей от данных?
  • Насколько точно можно измерить влияние нового изменения на систему?
  • Ухудшает ли улучшение одной модели или сигнала работу других?
  • Как быстро новые члены команды могут войти в курс дела?

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

Битва Новых Архитектур: Сравниваем Arc, GigAPI и DuckLake

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

Можно еще почитать тут: https://habr.com/ru/articles/955536/

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

🆚 Arc vs. GigAPI: Сравнительная таблица

Это прямые конкуренты, решающие задачу хранения и анализа временных рядов, но с разной философией.

Параметр Arc GigAPI
Основной подход Автономная Time-Series база данных «в одном файле» на базе DuckDB. Унифицированный слой для запросов и управления жизненным циклом данных (Lakehouse).
Стадия развития Альфа, не для продакшена. Открытая бета, активные релизы.
Архитектура Монолитный бинарный файл, простой запуск. Набор микросервисов (`aio`, `readonly`, `writeonly`, `compaction`).
Производительность (ingest) Заявлено до ~1.89 млн записей/сек (нативным протоколом). Субсекундные аналитические запросы. Производительность ingest зависит от бэкенда.
Протоколы ввода данных MessagePack (рекомендуемый), InfluxDB Line Protocol arc. InfluxDB Line Protocol, Native JSON. Планируется FlightSQL gigapi.
Управление данными ACID-транзакции, Time Travel, Schema Evolution (унаследовано от Lakehouse-архитектуры). Автоматическая компакция, перемещение данных (tiering) между FS и S3, удаление по TTL.
Лицензия AGPL-3.0 (важное ограничение для коммерческого использования). MIT (максимально разрешительная).

Ключевые отличия в подходах: Arc и GigAPI

Arc: Максимальная простота и скорость для старта

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

  • Идеология: “Батарейки в комплекте”. Arc предоставляет готовое решение с ACID-транзакциями, time travel и эволюцией схемы “из коробки”. Он спроектирован для максимальной простоты развертывания и сверхбыстрого приема данных.
  • Сценарий использования: Идеален для R&D, прототипирования и внутренних проектов, где нужна высокая производительность без сложной настройки.
  • Ключевой компромисс: Лицензия AGPL-3.0 требует, чтобы любое сетевое приложение, использующее Arc, также открывало свой исходный код. Это делает его неприменимым для многих коммерческих продуктов.
GigAPI: Операционная мощь для продакшена

GigAPI gigapi — это не база данных, а скорее интеллектуальный операционный слой или шлюз, который работает поверх ваших данных.

  • Идеология: “Оркестратор и оптимизатор”. GigAPI фокусируется на промышленной эксплуатации и автоматизации рутинных задач. Его микросервисы (`merge`, `move`, `drop`) следят за здоровьем хранилища: уплотняют мелкие файлы, перемещают старые данные в дешевое S3-хранилище и удаляют их по истечении срока жизни (TTL).
  • Сценарий использования: Построение зрелого, экономически эффективного и надежного пайплайна для временных рядов в production-среде. Разрешительная лицензия MIT делает его отличным выбором для бизнеса.
  • Ключевое преимущество: Архитектурная гибкость и фокус на снижении эксплуатационных расходов (OpEx).

А где же DuckLake?

DuckLake — это не база данных, а открытый табличный формат и расширение для DuckDB ducklake. Его цель — упростить создание Lakehouse, используя SQL в качестве слоя метаданных ducklake blog.

Представьте, что у вас есть набор Parquet-файлов в S3. Чтобы работать с ними как с единой таблицей и иметь транзакции, традиционно нужен сложный компонент вроде Hive Metastore или Nessie. DuckLake предлагает более простой путь:

Используйте обычную SQL-базу (например, DuckDB, SQLite или даже Postgres) для хранения всей метаинформации о файлах, версиях и схеме.

Таким образом, DuckLake — это фундаментальный строительный блок, а не готовое приложение. Он конкурирует с Apache Iceberg и Delta Lake, предлагая более простую альтернативу. Недавние обновления даже добавили совместимость с Iceberg, что делает его еще более мощным инструментом ducklake.select.

Сравнение с рынком: Альтернативы и выбор

Система Сильные стороны Слабые стороны / Риски
InfluxDB 3.0 Зрелая экосистема для временных рядов, Lakehouse архитектура “под капотом”. Стоимость для enterprise, привязка к своей экосистеме.
QuestDB Высокая скорость вставок и SQL-запросов, простой опыт TSDB. Менее универсален для “озер” на S3, чем конкуренты.
TimescaleDB Полная совместимость с экосистемой PostgreSQL. Привязанность к PostgreSQL и его модели масштабирования.
ClickHouse Универсальный OLAP-движок, мощные возможности для временных рядов, горизонтальное масштабирование. Высокие эксплуатационные расходы, сложность настройки кластера.

Когда что выбирать?

  • Выберите Arc, если вам нужен максимально быстрый старт для прототипа или внутреннего проекта, вы не боитесь альфа-версии и вас полностью устраивает лицензия AGPL-3.0.
  • Выберите GigAPI, если вы строите продакшн-систему, вам важна автоматизация рутинных задач (compaction, tiering, TTL) и нужна разрешительная лицензия MIT для коммерческого использования.
  • Используйте DuckLake, если вы уже работаете с DuckDB и хотите построить свой собственный, простой Lakehouse на базе Parquet-файлов, избегая сложности стека Hadoop/Spark.
  • Обратитесь к ClickHouse/Druid, когда нужны жесткие SLA, горизонтальное масштабирование и высокий параллелизм для тысяч одновременных пользователей.
  • Рассмотрите QuestDB/Timescale, если приоритетом является предельно простой опыт работы с TSDB или глубокая интеграция с экосистемой Postgres.

Заключение

Arc, GigAPI и DuckLake — яркие представители тренда на прагматичные и экономичные решения для данных.

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

Их появление говорит о том, что рынку нужны не только монструозные системы, но и решения с оптимальным соотношением “простота/стоимость/функциональность”.

Вот так выглядит:

services:
  gigapi:
    image: ghcr.io/gigapi/gigapi:latest
    container_name: gigapi
    hostname: gigapi
    restart: unless-stopped
    volumes:
      - ./data:/data
    ports:
      - "7971:7971"
      - "8082:8082"
    environment:
      - PORT=7971
      - GIGAPI_ENABLED=true
      - GIGAPI_MERGE_TIMEOUT_S=10
      - GIGAPI_ROOT=/data
      - GIGAPI_LAYERS_0_NAME=default
      - GIGAPI_LAYERS_0_TYPE=fs
      - GIGAPI_LAYERS_0_URL=file:///data
      - GIGAPI_LAYERS_0_GLOBAL=false
      - GIGAPI_LAYERS_0_TTL=12h
      - GIGAPI_LAYERS_1_NAME=s3
      - GIGAPI_LAYERS_1_TYPE=s3
      - GIGAPI_LAYERS_1_URL=s3://gateway.XXXXX/test/gigapi
      - GIGAPI_LAYERS_1_AUTH_KEY=XXXXX
      - GIGAPI_LAYERS_1_AUTH_SECRET=XXXXX
      - GIGAPI_LAYERS_1_GLOBAL=true
      - GIGAPI_LAYERS_1_TTL=0

А данные пишем так:

cat <<EOF | curl -X POST "http://localhost:7971/write?db=mydb" --data-binary @/dev/stdin
weather,location=us-midwest,season=summer temperature=82
weather,location=us-east,season=summer temperature=123
weather,location=us-west,season=summer temperature=111
EOF

Первый раз нужно отправить сообщение, что бы создалась база.

файлики пишет, но че то пока не на s3, видимо надо дождаться как они переедут с кеша на s3

Выше пример не сработал, точнее он работал, но не копировал данные на s3

вот это рабочий вариант

# docker-compose.yml
version: '3.8'

services:
  gigapi:
    build: . 
    container_name: gigapi
    restart: unless-stopped
    volumes:
      - ./gigapi_data:/data
    ports:
      - "7971:7971"
      - "8082:8082"
    environment:
      # --- Общие настройки GigAPI ---
      - GIGAPI_ROOT=/data 
      - HTTP_PORT=7971
      - LOGLEVEL=info
      - GIGAPI_UI=true

      # --- Конфигурация Слоя 0: Локальный кэш на диске ---
      - GIGAPI_LAYERS_0_NAME=local_cache
      - GIGAPI_LAYERS_0_TYPE=fs
      - GIGAPI_LAYERS_0_URL=file:///data/cache
      - GIGAPI_LAYERS_0_GLOBAL=false
      - GIGAPI_LAYERS_0_TTL=10m

      # --- Конфигурация Слоя 1: Хранилище Storj S3 ---
      - GIGAPI_LAYERS_1_NAME=storj_s3
      - GIGAPI_LAYERS_1_TYPE=s3
      - GIGAPI_LAYERS_1_URL=s3://gateway.storjshare.io/test/gigapi/data?url-style=path
      - GIGAPI_LAYERS_1_AUTH_KEY=XXXXXX
      - GIGAPI_LAYERS_1_AUTH_SECRET=XXXXX
      - GIGAPI_LAYERS_1_GLOBAL=true
      - GIGAPI_LAYERS_1_TTL=0

И пришлось серты обновить

# Dockerfile

# Берем за основу официальный образ gigapi
FROM ghcr.io/gigapi/gigapi:latest

# Переключаемся на пользователя root для установки пакетов
USER root

# Обновляем список пакетов и устанавливаем корневые сертификаты.
# Эта команда сначала пытается использовать 'apt-get' (для Debian/Ubuntu).
# Если эта команда завершается с ошибкой (оператор ||), то
# выполняется вторая команда с 'apk' (для Alpine).
# Это делает Dockerfile более универсальным.
RUN if command -v apt-get &> /dev/null; then \
        apt-get update && apt-get install -y --no-install-recommends ca-certificates && apt-get clean && rm -rf /var/lib/apt/lists/*; \
    elif command -v apk &> /dev/null; then \
        apk add --no-cache ca-certificates; \
    else \
        echo "Error: Neither apt-get nor apk found. Cannot install ca-certificates." >&2; \
        exit 1; \
    fi

# Возвращаемся к стандартному пользователю (если он есть)
# USER gigapi

Там кстати еще чатгпт апи можно вставить

И дашборды есть еще

Еще про s3 подобные архитектуры:
https://gavrilov.info/all/sozdaem-streaming-lakehouse-za-chas-rukovodstvo-po-risingwave-la

Cloudflare анонсирует платформу данных

*25 сентября 2025 г.*
*Мика Уайлд, Алекс Грэм, Жером Шнайдер*

https://blog.cloudflare.com/cloudflare-data-platform/


На неделе разработчиков в апреле 2025 года мы анонсировали публичную бета-версию R2 Data Catalog, полностью управляемого каталога Apache Iceberg поверх объектного хранилища Cloudflare R2. Сегодня мы развиваем эту область тремя новыми запусками:

  • Cloudflare Pipelines получает события, отправленные через Workers или HTTP, преобразует их с помощью SQL и загружает в Iceberg или в виде файлов в R2.
  • R2 Data Catalog управляет метаданными Iceberg и теперь выполняет постоянное обслуживание, включая уплотнение (compaction), для повышения производительности запросов.
  • R2 SQL — наш собственный распределенный SQL-движок, разработанный для выполнения запросов петабайтного масштаба к вашим данным в R2.

Вместе эти продукты составляют Платформу данных Cloudflare (Cloudflare Data Platform) — комплексное решение для приема, хранения и запроса аналитических данных.

Как и все продукты Платформы для разработчиков Cloudflare , все они работают на нашей глобальной вычислительной инфраструктуре. Они построены на открытых стандартах и совместимы. Это означает, что вы можете использовать свой собственный движок запросов для Iceberg — будь то PyIceberg, DuckDB или Spark, — подключаться к другим платформам, таким как Databricks и Snowflake, и не платить за исходящий трафик (egress fees) при доступе к вашим данным.

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

Если вы готовы начать прямо сейчас, следуйте нашему руководству по Платформе данных для пошагового создания конвейера, который обрабатывает события и доставляет их в таблицу R2 Data Catalog, к которой затем можно будет делать запросы с помощью R2 SQL.

Как мы пришли к созданию Платформы данных?

Мы запустили объектное хранилище `R2 Object Storage` в 2021 году с радикальной ценовой стратегией: никакой платы за исходящий трафик (egress fees) — это плата за пропускную способность, которую традиционные облачные провайдеры взимают за выгрузку данных, фактически держа ваши данные в заложниках.

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

Apache Iceberg. Iceberg — это формат таблиц, который предоставляет возможности, подобные базам данных (включая обновления, ACID-транзакции и эволюцию схемы), поверх файлов данных в объектном хранилище. Другими словами, это слой метаданных, который сообщает клиентам, какие файлы данных составляют определенную логическую таблицу, каковы их схемы и как эффективно их запрашивать.

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

Однако пользователям все еще приходилось управлять всей инфраструктурой метаданных самостоятельно. Мы поняли, что можем решить эту проблему, и так появился `R2 Data Catalog` — наш управляемый каталог Iceberg. Но оставалось несколько пробелов:

  1. Как загружать данные в таблицы Iceberg?
  2. Как оптимизировать их для повышения производительности запросов?
  3. Как извлекать ценность из данных, не размещая собственный движок запросов?

Далее мы рассмотрим, как три продукта, составляющие Платформу данных, решают эти задачи.

Cloudflare Pipelines

Аналитические таблицы состоят из событий, произошедших в определенный момент времени. Прежде чем вы сможете запрашивать их с помощью Iceberg, их нужно принять, структурировать по схеме и записать в объектное хранилище. Эту роль выполняют Cloudflare Pipelines.

Созданные на базе `Arroyo` (движка потоковой обработки, который мы приобрели в этом году), `Pipelines` получают события, преобразуют их с помощью SQL-запросов и направляют (sinks) в R2 и R2 Data Catalog.

`Pipelines` организованы вокруг трех ключевых объектов:

  • Streams (Потоки): Способ получения данных в Cloudflare. Это надежные буферизованные очереди, которые принимают события по HTTP или через привязку к Cloudflare Worker.
  • Sinks (Приемники): Определяют место назначения ваших данных. Мы поддерживаем загрузку в R2 Data Catalog, а также запись необработанных файлов в R2 в формате JSON или Apache Parquet.
  • Pipelines (Конвейеры): Соединяют потоки и приемники через SQL-преобразования, которые могут изменять события перед их записью.

Например, вот конвейер, который принимает события из источника данных о кликах (clickstream) и записывает их в Iceberg, отфильтровывая ботов и события, не являющиеся просмотрами страниц:

INSERT into events_table
SELECT
 user_id,
 lower(event) AS event_type,
 to_timestamp_micros(ts_us) AS event_time,
 regexp_match(url, '^https?://([^/]+)')[1] AS domain,
 url,
 referrer,
 user_agent
FROM events_json
WHERE event 'page_view'
 AND NOT regexp_like(user_agent, '(?i)bot|spider');

SQL-преобразования позволяют вам:

  • Приводить данные к нужной схеме и нормализовать их.
  • Фильтровать события или разделять их на разные таблицы.
  • Удалять конфиденциальную информацию перед сохранением.
  • Разворачивать вложенные массивы и объекты в отдельные события.

`Cloudflare Pipelines` доступны сегодня в открытой бета-версии. Во время беты мы не взимаем плату за `Pipelines`, однако хранение и операции в `R2` оплачиваются по стандартным тарифам blog.cloudflare.com.

R2 Data Catalog

Мы запустили открытую бету `R2 Data Catalog` в апреле и были поражены откликом blog.cloudflare.com. Начать работу с Iceberg стало просто — не нужно настраивать кластер баз данных или управлять инфраструктурой.

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

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

Сегодня мы запускаем поддержку уплотнения в `R2 Data Catalog`. Включить его для вашего каталога очень просто:

$ npx wrangler r2 bucket catalog compaction enable mycatalog

Во время открытой беты мы не взимаем плату за `R2 Data Catalog`. Ниже наши предполагаемые будущие цены:

Услуга Цена*
Хранилище R2 (стандартный класс) $0.015 за ГБ в месяц (без изменений)
Операции R2 класса A $4.50 за миллион операций (без изменений)
Операции R2 класса B $0.36 за миллион операций (без изменений)
Операции Data Catalog $9.00 за миллион операций каталога
– Обработка данных уплотнением $0.005 за ГБ + $2.00 за миллион объектов
Исходящий трафик (Egress) $0 (без изменений, всегда бесплатно)

*\*цены могут быть изменены до официального выпуска.*

R2 SQL

Иметь данные в `R2 Data Catalog` — это только первый шаг. Реальная цель — извлечь из них ценность. Традиционно это означает настройку и управление Spark, Trino или другим движком запросов. А что, если бы вы могли выполнять запросы прямо на Cloudflare?

Теперь можете. Мы создали движок запросов, специально разработанный для `R2 Data Catalog` и пограничной инфраструктуры Cloudflare. Мы называем его R2 SQL, и он доступен сегодня в виде открытой беты.

Выполнить запрос к таблице `R2 Data Catalog` с помощью Wrangler так же просто, как:

$ npx wrangler r2 sql query "{WAREHOUSE}" "SELECT user_id, url FROM events WHERE domain = 'mywebsite.com'"

Способность Cloudflare планировать вычисления в любой точке своей глобальной сети лежит в основе `R2 SQL`. Это позволяет нам обрабатывать данные прямо там, где они находятся. Результатом является полностью бессерверный опыт для пользователей.

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

Подводя итоги

Сегодня вы можете использовать Платформу данных Cloudflare для приема событий в `R2 Data Catalog` и их запроса через `R2 SQL`. В первой половине 2026 года мы планируем расширить возможности всех этих продуктов, включая:

  • Интеграцию с `Logpush`, чтобы вы могли преобразовывать, хранить и запрашивать свои логи прямо в Cloudflare.
  • Пользовательские функции через `Workers` и поддержку обработки с состоянием для потоковых преобразований.
  • Расширение функционала `R2 SQL` для поддержки агрегаций и объединений (joins).
 No comments   24 d   Cloud   Data
 No comments   24 d   Art nft   NFT

Потоковая обработка: Stateful и Stateless

Современные системы обработки данных все чаще работают с непрерывными потоками событий — от отслеживания активности пользователей на сайтах до мониторинга IoT-устройств. Этот подход позволяет анализировать информацию в реальном времени. В основе таких систем лежит выбор между двумя фундаментальными парадигмами: потоковой обработкой с состоянием (stateful) и без него (stateless).

А все эти изыски пошли от этого поста:

I haven't dug deep into this project, so take this with a grain of salt. // пишет про ArkFlow
ArkFlow is a "stateless" stream processor, like vector or benthos (now Redpanda Connect). These are great for routing data around your infrastructure while doing simple, stateless transformations on them. They tend to be easy to run and scale, and are programmed by manually constructing the graph of operations.
Arroyo (like Flink or Rising Wave) is a "stateful" stream processor, which means it supports operations like windowed aggregations, joins, and incremental SQL view maintenance. Arroyo is programmed declaratively via SQL, which is automatically planned into a dataflow (graph) representation. The tradeoff is that state is hard to manage, and these systems are much harder to operate and scale (although we've done a lot of work with Arroyo to mitigate this!).
I wrote about the difference at length here: https://www.arroyo.dev/blog/stateful-stream-processing

А про маленького Stateless зверька ArkFlow будет потом статейка. В прочем можете уже посмотреть и раньше.

Потоковая обработка с состоянием (stateful) означает, что система способна запоминать информацию о ранее обработанных событиях. Это позволяет выполнять сложные операции, такие как агрегации, объединения (joins) и вычисления в “окнах” времени.

В этой статье мы разберем, в чем разница между этими подходами, когда стоит выбирать тот или иной, и как современные движки, такие как Apache Flink или RisingWave, справляются со сложностями хранения состояния. Про “Восходящую волну” и делал тестик тут https://gavrilov.info/all/sozdaem-streaming-lakehouse-za-chas-rukovodstvo-po-risingwave-la

Потоковая обработка без состояния (Stateless)

Многие системы потоковой обработки являются stateless. Это означает, что они обрабатывают каждое событие изолированно, не имея возможности “помнить” информацию о данных, которые видели ранее.

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

В потоковой обработке отсутствие состояния также означает, что система выполняет только простые операции преобразования или фильтрации (в SQL-терминах это `SELECT` и `WHERE`). Сложные операции, требующие группировки или объединения данных (`GROUP BY`, `JOIN`, `ORDER BY`), в таких системах невозможны.

Преимущества stateless-систем:

  • Простота эксплуатации: Их легко запускать в кластерных системах вроде Kubernetes или в бессерверных средах типа AWS Lambda.
  • Легкость масштабирования: Достаточно просто добавить больше обработчиков (workers).
  • Изолированные сбои: Выход из строя одного узла не влияет на другие.
  • Быстрое восстановление: Не нужно восстанавливать какое-либо состояние.

Если ваши задачи укладываются в эти ограничения (нет агрегаций, нет необходимости группировать данные), вам следует использовать stateless-обработку. Часто для таких задач даже не нужен специализированный движок потоковой обработки — достаточно сервиса, который читает события из источника (например, Apache Kafka), выполняет простую логику и записывает результат.

Примеры использования:

  • Сбор метрик с серверов, их преобразование и отправка в базу данных для мониторинга.
  • Обработка логов: фильтрация, удаление конфиденциальных данных, изменение формата.

Пример простого SQL-запроса, который может быть выполнен в stateless-системе:

SELECT timestamp, redact(log_text) -- Выбираем время и скрываем часть текста лога
FROM logs
WHERE log_level = 'ERROR'; -- Только для событий с уровнем 'ERROR'

Добавление состояния (Stateful)

Однако большинство бизнес-задач требуют запоминания информации о прошлых событиях, то есть требуют наличия состояния decodable.co. Вместе с состоянием часто возникает необходимость в перераспределении (shuffling) данных между узлами кластера.

Пример: Агрегации с состоянием для обнаружения мошенничества

Представим, что e-commerce сайт должен обнаруживать и блокировать мошеннические операции с кредитными картами. Один из эффективных признаков мошенничества — “сколько неудачных транзакций было у этого пользователя за последние 24 часа”.

С помощью SQL это можно выразить так:

SELECT
  user_id,
  count(*) as failed_count
FROM transactions
WHERE
  status = 'FAILED'
GROUP BY
  user_id,
  -- hop - это функция скользящего окна в некоторых диалектах SQL
  hop(INTERVAL '5 seconds', INTERVAL '24 hours');

SQL-запрос преобразуется в граф операторов (конвейер), где каждый шаг выполняет свою часть логики.

Схема конвейера обработки запроса

Этот запрос подсчитывает количество неудачных событий для каждого `user_id`. Чтобы получить итоговое число, нам нужно, чтобы все события для одного и того же пользователя (например, “bob”) попадали на один и тот же вычислительный узел. Этот процесс перенаправления данных называется перераспределением (shuffling) и в SQL вводится оператором `GROUP BY`.

Пример перераспределения данных

Но чтобы посчитать количество событий за 24 часа, система должна хранить эти события на протяжении всего окна. Это и есть состояние (state). Оно необходимо для любого запроса, который вычисляет агрегаты по времени.

Пример: Состояние в ETL-конвейерах

Состояние полезно даже в задачах, которые на первый взгляд кажутся простыми. Например, при загрузке событий в озерo данных ( вроде Amazon S3). Казалось бы, это stateless-операция: получил событие, преобразовал, записал.

Такой подход будет работать при небольшом объеме данных. Но с ростом трафика он приведет к проблемам с производительностью: запись множества мелких файлов в S3 неэффективна и сильно замедляет последующее чтение данных.

Решение с использованием состояния:
Stateful-движок может перераспределять события по их типу (`event_type`), направляя каждый тип на свой узел. Затем, используя состояние, он накапливает события в буфере в памяти, пока не соберется достаточно большой пакет (например, 8-16 МБ), и только потом записывает его в S3 одним большим файлом. Это значительно повышает производительность как записи, так и чтения.

Как и где хранится состояние?

Разные движки потоковой обработки решают эту задачу по-разному skyzh.dev:

Движок/Система Подход к хранению состояния Пояснение
Apache Flink Локально на узле (в памяти или RocksDB) RocksDB — это встраиваемая key-value база данных, основанная на LSM-деревьях. Она позволяет хранить огромные объемы состояния, но сложна в настройке и может вызывать проблемы с I/O диска из-за операций сжатия (compaction).
ksqlDB / Kafka Streams Гибридное (в Kafka и локально) Часть состояния хранится в топиках Apache Kafka, а состояние для оконных функций — локально на узлах в памяти или RocksDB.
RisingWave / Arroyo Удаленно (в S3 или FoundationDB) с локальным кэшем Современный подход, при котором основное хранилище состояния отделено от вычислений. На вычислительных узлах находится только “горячий” кэш активных данных. Это значительно ускоряет масштабирование и восстановление после сбоев, так как не нужно перемещать терабайты данных между узлами.
Схема LSM дерева

Согласованное сохранение состояния (Checkpointing)

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

Для обеспечения отказоустойчивости stateful-системы используют механизм контрольных точек (checkpointing) — периодическое создание согласованных “снимков” состояния всего конвейера и сохранение их в надежное хранилище (например, S3).

Ключевая задача здесь — гарантировать семантику “exactly-once” (ровно один раз). Это означает, что даже в случае сбоев и восстановлений каждое входящее событие будет обработано и повлияет на итоговое состояние ровно один раз, без потерь и дубликатов export.arxiv.org.

Для этого используется элегантный алгоритм Чанди-Лэмпорта. Его суть в том, что через поток данных пропускаются специальные маркеры — барьеры контрольных точек. Когда оператор получает барьеры от всех своих входов, он делает снимок своего текущего состояния и пересылает барьер дальше.

Поток барьеров контрольных точек

Современные системы делают этот процесс максимально эффективным:

  • Асинхронность: Создание контрольной точки не блокирует обработку новых данных.
  • Инкрементальность: В хранилище отправляются только измененные данные, а не всё состояние целиком.

Это позволяет создавать контрольные точки очень часто (например, каждые 10 секунд). В случае сбоя системе потребуется перечитать и обработать заново лишь данные за последние 10 секунд, что делает восстановление почти мгновенным.

Итог

Потоковая обработка без состояния (stateless) проста и эффективна для ограниченного круга задач, таких как фильтрация или простое преобразование данных.

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

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

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

А это тут пока положу, а то забуду :)

https://habr.com/ru/articles/774870 – Землю — крестьянам, gRPC — питонистам. Она про grpc питонячий.

Open Source порталы разработки и что такое IDP

На рынке внутренних порталов разработчика существует один явный лидер в категории open source — Backstage. Большинство других популярных решений, таких как Port, являются коммерческими (SaaS) продуктами, хотя они и могут предлагать open source компоненты для интеграции https://internaldeveloperplatform.org/developer-portals/port/

Поэтому основной фокус в open source сегменте приходится именно на Backstage, который был создан в Spotify и позже передан в Cloud Native Computing Foundation (CNCF).

Ключевое решение: Backstage

Backstage — это не готовый продукт, а фреймворк для создания собственного портала разработчика https://cloudomation.com/cloudomation-blog/5-internal-developer-portals-and-what-software-engineers-say-about-them/. Это его главное преимущество и одновременно главный недостаток. Он предоставляет базовые строительные блоки и архитектуру, на основе которых компании могут построить портал, идеально соответствующий их процессам и инструментам.

Кстати очень интересная статья про порталы, платформы и их различия.

Картинка от портала  Cortex – ну прям огонь сайт у них https://www.cortex.io.

Cloudomation Guide – Building Internal Developer Platforms.pdf есть еще гайд обобщенный. А основная концепция конечно тут https://internaldeveloperplatform.org

Основные компоненты Backstage:

  1. Software Catalog: Единый реестр для всех программных активов компании (микросервисы, библиотеки, веб-сайты, ML-модели и т.д.). Позволяет централизовать метаданные, информацию о владельцах, зависимостях и состоянии.
  2. Software Templates (Scaffolder): Инструмент для создания новых проектов по заранее подготовленным шаблонам. Это стандартизирует первоначальную настройку сервисов, CI/CD пайплайнов, репозиториев и т.д.
  3. TechDocs: Решение для создания, поддержки и отображения технической документации по принципу “docs-as-code”, когда документация хранится вместе с кодом.
  4. Плагины: Экосистема Backstage строится вокруг плагинов. Существует огромное количество готовых плагинов для интеграции с AWS, Kubernetes, GitHub, CI/CD системами, системами мониторинга и многими другими. Если нужного плагина нет, его можно разработать самостоятельно.

Сравнение подходов: Build vs. Buy

Поскольку настоящий open source конкурент у Backstage практически отсутствует, наиболее корректно сравнить его не с другим open source решением, а с подходом использования коммерческих SaaS-платформ, ярким представителем которых является Port.

  • Port** — это коммерческий продукт, который предлагает готовый к использованию портал. Его философия заключается в гибкой модели данных на основе “blueprints” (шаблонов сущностей) и взаимосвязей между ними. Port позволяет быстро агрегировать данные из различных источников и построить каталог без необходимости развертывания и поддержки сложной инфраструктуры 10-best-internal-developer-portals-to-consider. Хотя ядро продукта закрыто, его интеграции и экспортеры данных являются открытыми [internaldeveloperplatform.org](https://internaldeveloperplatform.org/developer-portals/port/).

Сравнительная таблица: Backstage vs. Коммерческие IDP (на примере Port)

Критерий Backstage (Open Source) Коммерческие решения типа Port (SaaS)
Модель лицензирования Open Source (Apache 2.0). Бесплатно. Коммерческая (SaaS). Платная подписка.
Философия / Подход Фреймворк для создания портала. “Построй свой дом”. Готовый продукт для настройки портала. “Купи и настрой квартиру”.
Сложность внедрения Высокая. Требуется разработка, развертывание и поддержка. Есть кривая обучения [cloudomation.com](https://cloudomation.com/cloudomation-blog/5-internal-developer-portals-and-what-software-engineers-say-about-them/). Низкая / Средняя. Быстрый старт, не требует своей инфраструктуры.
Требования к команде Нужна выделенная команда платформенных инженеров для разработки и поддержки портала. Может управляться одним или несколькими DevOps-инженерами. Не требует навыков фронтенд-разработки.
Гибкость и кастомизация Максимальная. Можно изменить и доработать абсолютно все, создать уникальные плагины и логику. Высокая, но ограничена возможностями платформы. Кастомизация интерфейса и логики возможна в рамках, заданных вендором.
Инфраструктура Требует собственной инфраструктуры для хостинга (обычно Kubernetes), базы данных, CI/CD для самого портала. Не требует. Хостится и управляется вендором.
Экосистема и интеграции Огромная, управляемая сообществом. Большое количество open source плагинов. Управляется вендором. Интеграции создаются вендором, но часто есть открытые API и экспортеры данных.
Общая стоимость владения (TCO) Скрытая и высокая. Лицензия бесплатна, но основные затраты — это зарплаты команды разработки и поддержки, а также стоимость инфраструктуры. Прозрачная и предсказуемая. Основные затраты — стоимость подписки.
Поддержка Сообщество (Slack, GitHub Issues). Коммерческая поддержка от вендора (SLA, выделенный менеджер).

Выбор между open source фреймворком вроде `Backstage` и коммерческим продуктом — это классический выбор между “Build” (создавать) и “Buy” (покупать).

  1. `Backstage` — это стратегическая инвестиция. Это мощное решение для крупных или технологически зрелых компаний, у которых уже есть выделенная платформенная команда и которые готовы вкладывать ресурсы в создание идеально подогнанного под себя инструмента. `Backstage` дает полный контроль, избавляет от зависимости от вендора (vendor lock-in) и позволяет решать уникальные задачи, которые не могут покрыть коробочные продукты.
  1. Коммерческие IDP (такие как Port) — это тактическое решение для быстрого результата. Они идеально подходят для малых и средних компаний, или для крупных организаций, которые хотят быстро запустить портал и проверить гипотезы, не формируя для этого отдельную команду разработки. Этот подход обеспечивает быстрый старт, предсказуемые затраты и перекладывает всю головную боль по поддержке и развитию платформы на плечи вендора.
Рекомендации

Выбирайте `Backstage`, если:

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

Рассмотрите коммерческие решения (типа Port), если:

  • Вам нужен результат “здесь и сейчас” с минимальными первоначальными усилиями.
  • У вас нет ресурсов на формирование команды для разработки собственного портала.
  • Стандартного или предложенного вендором функционала достаточно для решения ваших задач.
  • Вы предпочитаете прозрачную модель оплаты (SaaS-подписка) вместо скрытых затрат на разработку и поддержку.
  • Вам важна гарантированная коммерческая поддержка с четким SLA.

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

Ниже небольшой гайд на основе дока выше Cloudomation Guide – Building Internal Developer Platforms.pdf

Руководство

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

***

Кратко о чем все это?

Ниже представлен обзор внутренних платформ для разработчиков (Internal Developer Platforms, или IDP). Поскольку инженерные команды сталкиваются с растущей сложностью, IDP становятся решением для снижения разногласий между разработкой и эксплуатацией.

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

Основные тезисы:

  • IDP — это платформы самообслуживания, созданные инженерами платформ для оптимизации разработки программного обеспечения за счет автоматизации развертываний, конфигураций и управления средами.
  • Преимущества: Сокращение времени, затрачиваемого на настройку и отладку, снижение когнитивной нагрузки на разработчиков, повышение надежности и соответствия требованиям, а также более высокая операционная эффективность.
  • Каждая IDP уникальна, но обычно состоит из фронтенда, бэкенда и других интегрированных инструментов.
  • Ключевые возможности IDP должны включать: API, пользовательский интерфейс, автоматизацию, механизмы ограничений (например, политики), документацию и возможность обнаружения сервисов (discoverability).
  • Для создания по-настоящему целостной IDP необходимо сосредоточиться на интеграции всех необходимых инструментов и сервисов.
  • При внедрении IDP могут возникнуть следующие проблемы: попытка сделать все сразу (и не достичь ничего), нехватка ресурсов и бюджета, невозможность поддерживать каталог программного обеспечения в актуальном состоянии и недостаток коммуникации между людьми.
  • Обосновывая необходимость внедрения IDP, подкрепляйте свои аргументы данными и связывайте их с рисками и результатами, которые больше всего волнуют ваше руководство.

***

Содержание

  1. Что такое IDP?
  2. Зачем нужны IDP?
  3. Как работают IDP?
  4. Обоснование необходимости IDP для бизнеса
  5. Лучшие практики для создания IDP
  6. Инструменты платформенной инженерии для создания IDP
  7. 3 проблемы при создании IDP
  8. Ресурсы

1. Что такое IDP?

Внутренние платформы для разработчиков (IDP) лежат в основе дисциплины платформенной инженерии (Platform Engineering).

Пояснение:
Внутренняя платформа для разработчиков — это, по сути, продукт, предназначенный для разработчиков внутри организации. Она предоставляет им доступ по принципу самообслуживания к технической инфраструктуре и рабочим процессам, таким как конвейеры развертывания или облачные ресурсы. пост на dev.to. Ключевая идея — относиться к своей внутренней платформе как к продукту, а к разработчикам — как к клиентам. еще пост с dev.to. Это позволяет им не ждать выполнения заявок в отдел эксплуатации и не нести полную ответственность за инфраструктуру, как в модели «you build it, you run it».

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

Понимание внутренних платформ для разработчиков

На схеме ниже показаны ключевые концепции, лежащие в основе IDP.

  • Подходы «Инфраструктура как код» (As-Code Approaches): Акцент на автоматизацию и документирование через код.
  • «Золотые пути» (Golden Paths): Предоставление заранее определенных, проверенных и поддерживаемых путей для выполнения типовых задач (например, создание нового сервиса, развертывание в среде). Разработчики могут легко следовать этим путям, будучи уверенными в результате.
  • Самообслуживание (Self-Service): Позволяет разработчикам самостоятельно использовать платформу без необходимости обращаться в другие команды.
  • Управление как продуктом (Managed like a product): У платформы есть свой жизненный цикл выпуска, владелец продукта и дорожная карта развития.
  • Инженеры платформы (Platform Engineers): Создают и поддерживают IDP, фокусируясь на ценности для разработчиков.
  • Разработчики ПО (Software Developers): Основные пользователи, которые взаимодействуют с IDP.
Функции IDP

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

Это лишь примеры функций, которые может иметь IDP. Каждая IDP уникальна для организации, которая ее использует. Часто они создаются с нуля или сильно кастомизируются под нужды компании.


2. Зачем нужны IDP?

По мере усложнения процесса поставки ПО организации сталкиваются с фрагментированными практиками DevOps, несогласованными рабочими процессами и операционной неэффективностью. От разработчиков ожидают, что они будут управлять инфраструктурой, конвейерами CI/CD, политиками безопасности и мониторингом, что часто приводит к когнитивной перегрузке и снижению производительности. Именно здесь на помощь приходят платформенная инженерия и IDP.

Раскрывая мощь IDP
  1. Ускорение циклов разработки: Оптимизированное развертывание сокращает время, затрачиваемое на настройку и отладку.
  2. Снижение когнитивной нагрузки на разработчиков: Упрощенное управление инфраструктурой позволяет сосредоточиться на написании кода.
  3. Повышение надежности и соответствия требованиям (Compliance): Обеспечивает последовательное применение политик безопасности и соответствия во всех развертываниях.
  4. Повышение инженерной эффективности: Автоматизирует управление ресурсами, повышая операционную эффективность.

3. Как работают IDP?

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

  • Фронтенд IDP
  • Бэкенд IDP
  • Множество других инструментов, интегрированных с IDP
  • Фронтенд: Пользовательский интерфейс для доступа разработчиков к IDP. Часто это внутренний портал разработчика (Internal Developer Portal).
  • Бэкенд: Управляет интеграцией и автоматизацией с другими инструментами. Эту роль часто выполняет оркестратор платформы.
  • Интегрированные инструменты: Различные инструменты, которые работают с IDP для выполнения ключевых процессов (CI/CD, мониторинг, безопасность и т.д.).
Архитектура

Следующая диаграмма архитектуры, основанная на модели CNOE (Cloud Native Operational Excellence), дает более детальное представление.

Ранее писал про Rainbond китайский, там немного другой акцент, но их архитектура тоже интересная, а так как это опенсорс, то можно свой такой запилить, но переводить придется :)

В этой диаграмме «Портал разработчика» (`Developer Portal`) является фронтендом IDP. Компонент «Оркестрация рабочих процессов» (`Workflow Orchestration`) будет бэкендом.

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

Ключевая функциональность IDP

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

Таким образом, бэкенд IDP, как правило, должен быть сильным в двух типах функциональности: №1 Интеграция и №2 Автоматизация.

  • Интеграция: Объединение разнообразных инструментов и сервисов в единую систему.
  • Автоматизация: Связывание и оркестрация существующих конвейеров автоматизации.

4. Обоснование необходимости IDP для бизнеса

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

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

Вот как можно обосновать необходимость IDP, обращаясь к четырем ключевым проблемам руководителей: Масштаб, Затраты, Риски и Управление.

1. Масштаб: Предоставление организации возможности двигаться быстрее
  • Проблема руководителя: Как мы можем масштабировать наши инженерные команды и поставку ПО без узких мест?
  • Обоснование IDP: IDP повышает производительность, абстрагируя повторяющиеся, низкоценные задачи. Она дает командам приложений возможность самостоятельно обслуживать инфраструктуру, CI/CD, тестирование и развертывание стандартизированным и безопасным способом.
  • Бизнес-результаты:
    • Повышение скорости работы команд приложений и организации в целом.
    • Быстрая доставка большей бизнес-ценности, поскольку команда разработки может сосредоточиться на коде.
    • Возможность масштабирования без линейного увеличения найма DevOps-инженеров.
  • Как это сделать: Оцените, сколько времени команды приложений тратят на борьбу с инфраструктурой и инструментами развертывания, и сколько — на работу над своим основным приложением. Используйте эти данные, чтобы обосновать необходимость IDP и показать, как она может высвободить время для основной задачи, что напрямую влияет на бизнес-ценность. Визуализируйте это, чтобы подчеркнуть, каким объемом инфраструктуры приходится управлять командам приложений, и сравните это с тем, как это могло бы выглядеть.

*(В оригинальном документе здесь показаны два слайда из презентации PlatformCon23, представляющие “текущее состояние” и “будущее состояние”. Текущее состояние показывает, как команда из 50 разработчиков приложений вынуждена вручную взаимодействовать с разрозненным набором инструментов. Будущее состояние показывает, как команда платформы предоставляет единый, унифицированный слой, который абстрагирует эту сложность, позволяя командам приложений работать более эффективно.)*

Обратите внимание сколько кубиков вверху, а сколько внизу. В России кстати очень быстро вырывается вперед разработка на фреймворках streamlit, они почти ничего не делают повторно, если развернули хоть раз его с авторизацией и ипишками – в основном только ui колбасят. Но часто такие инициативы не вырастают сильно, их обычно давят в зародыше, так как они не соответствуют общему формату и не хотят делать все остальные кубики или не умеют – в общем похожи они на shadow it. Но если же им каким, то образом это удалось, то потом их не остановить и придя к ним через год, можно увидел второй прод, полностью зеркальный :) и сделал его кто-то один вечерами.

2. Затраты: Оптимизация за счет масштабирования и повторного использования
  • Проблема руководителя: Как нам контролировать растущие расходы на облако и инженерию?
  • Обоснование IDP: Платформенная инженерия сокращает дублирование усилий и консолидирует управление инфраструктурой. IDP способствует экономически эффективному масштабированию, обеспечивая прозрачность и контроль на протяжении всего жизненного цикла ПО. Централизация позволяет совместно использовать ресурсы, проактивно отслеживать затраты и автоматически высвобождать неиспользуемые активы (например, тестовые среды).
  • Бизнес-результаты:
    • Улучшенная прозрачность и предсказуемость затрат.
    • Снижение общей стоимости владения (TCO) за счет оптимизации ресурсов.
    • Большая рентабельность инвестиций (ROI) в облачную инфраструктуру.
  • Важный момент: Команды платформы могут отслеживать метрики использования и отключать неиспользуемые среды.
3. Риски: Сокращение точек отказа и операционных угроз
  • Проблема руководителя: Какие риски угрожают нашей способности поставлять продукт надежно и безопасно?
  • Обоснование IDP: IDP минимизирует операционные риски и риски безопасности путем стандартизации процессов по всем направлениям — конвейеры CI/CD, развертывание, наблюдаемость (observability), оповещения и аутентификация.
  • Бизнес-результаты:
    • Снижение риска сбоев в продакшене.
    • Централизация ключевых сервисов, таких как развертывание, управление идентификацией и логирование.
    • Принудительное применение политик безопасности и соответствия на уровне платформы.
  • Примеры устраняемых рисков:
    • Задержки в поставке из-за нестабильных конвейеров.
    • Утечки данных из-за неверно настроенных систем аутентификации.
    • Непрохождение аудита из-за несогласованного логирования или дрифта соответствия требованиям.
4. Управление (Governance): Обеспечение согласованности и соответствия требованиям в масштабе
  • Проблема руководителя: Как нам поддерживать контроль, не замедляя команды?
  • Обоснование IDP: С IDP управление становится встроенным. От шаблонов до API, команды платформы могут кодировать стандарты и лучшие практики непосредственно в опыт разработчика.
  • Бизнес-результаты:
    • Проактивное управление и применение политик.
    • Улучшенная аудитопригодность и соответствие нормативным требованиям.
    • Формирование культуры инженерного совершенства.
Подкрепление доводов данными

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

Итоговые мысли: Что не дает спать руководителям?

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

  • Скорость выхода на рынок (Speed to market): Сможем ли мы поставлять продукт быстрее конкурентов?
  • Надежность: Выдержат ли наши системы нагрузку?
  • Безопасность и соответствие требованиям (Security & Compliance): Уязвимы ли мы для взломов или аудитов?
  • Масштабируемость: Сможем ли мы расти, не теряя контроля?

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


5. Лучшие практики для создания IDP

Этот раздел основан на идеях, вдохновленных видео Виктора Фарчича «От нуля до полностью работающей платформы для разработчиков за 5 шагов!». Он описывает не столько шаги, сколько ключевые возможности, которые должна иметь IDP, чтобы быть полезной.

5 ключевых возможностей IDP (по версии Виктора Фарчича):

  1. API
  2. Управление состоянием (State management)
  3. Одноразовые действия / Рабочие процессы (One-shot actions / Workflows)
  4. RBAC и Политики (RBAC & Policies)
  5. Пользовательские интерфейсы (опционально)

Наш взгляд на ключевые возможности (немного измененный и дополненный):

  1. API: Программный интерфейс для взаимодействия с платформой.
  2. Пользовательские интерфейсы (не опционально): Удобный способ для разработчиков взаимодействовать с платформой.
  3. Автоматизация: Включает как одноразовые действия (например, запуск сборки), так и управление состоянием (например, поддержание среды в нужном состоянии).
  4. Ограничения (Constraints): Политики, управление доступом на основе ролей (RBAC) и т.д.
  5. Документация и обнаруживаемость (Discoverability): Возможность легко находить сервисы, их владельцев и документацию.
Как это поможет мне построить платформу?

Если вы подумаете о проблемах, с которыми вы недавно сталкивались как инженер платформы или DevOps-инженер, вы, вероятно, сможете соотнести их с одной из описанных возможностей.

Некоторые примеры:

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

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


6. Инструменты платформенной инженерии для создания IDP

В этой статье рассматривается, как структурировать IDP, с разбивкой по ключевым компонентам и с примерами инструментов, которые вы можете использовать.

Категоризация инструментов и компонентов

Мы классифицируем эти инструменты, используя «референсную архитектуру», популяризированную `platformengineering.org`. Эта структура разбивает экосистему на пять основных компонентов, известных как «плоскости» (`planes`):

  • Плоскость управления разработчика (`Developer Control Plane`): Все компоненты, через которые разработчики взаимодействуют с платформой. Обычно включает GUI/порталы, контроль версий, облачные среды разработки (CDE), а также стандарты конфигурации, которые разработчики поддерживают сами.
  • Плоскость интеграции и доставки (`Integration & Delivery Plane`): Здесь происходит вся автоматизация. Инструменты CI/CD, автоматизация инфраструктуры и другие оркестраторы платформы обычно являются частью этой плоскости.
  • Плоскость мониторинга и логирования (`Monitoring & Logging Plane`): Как следует из названия, здесь находятся все инструменты наблюдаемости (observability).
  • Плоскость безопасности (`Security Plane`): Управление секретами, инструменты политик и другие инструменты безопасности.
  • Плоскость ресурсов (`Resource Plane`): Вычислительные ресурсы и хранилища.
Пример: Создание внутренней платформы для разработчиков

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

Плоскость управления разработчика

№1 Портал разработчика (`Developer Portal`)

  • Почему это важно: Внутренние порталы разработчиков служат единым интерфейсом и позволяют разработчикам, командам и инженерам-менеджерам обнаруживать сервисы, отслеживать владение, применять стандарты и улучшать программное обеспечение.
  • Инструменты для рассмотрения:
    • Backstage: Популярный open-source фреймворк для создания порталов разработчиков, созданный Spotify.
    • Port: Платформа для создания внутреннего портала разработчика с no-code подходом, что облегчает быстрый старт.
    • Cortex: Корпоративный внутренний портал разработчика, созданный для ускорения пути к инженерному совершенству. [cloudomation.com](https://cloudomation.com/cloudomation-blog/5-internal-developer-portals-and-what-software-engineers-say-about-them/)
    • Atlassian Compass: Компонентный каталог для отслеживания компонентов и команд, которые за ними стоят.

№2 Облачные среды разработки (`Cloud Development Environments, CDEs`)

  • Почему это важно: CDE — это удаленные среды разработки, размещенные в облаке или локально. CDE позволяют разработчикам работать в согласованных, стандартизированных средах, что устраняет проблемы «у меня на машине все работает».
  • Инструменты для рассмотрения:
    • Gitpod: Позволяет запускать безопасные, контекстно-насыщенные среды для разработчиков в корпоративном масштабе.
    • Coder: Предоставляет безопасные среды разработки для разработчиков и их агентов.
Плоскость интеграции и доставки

№1 Конвейер CI (`CI Pipeline`)

  • Почему это важно: Автоматизирует проверку кода, тестирование и обеспечивает более быстрые циклы обратной связи.
  • Инструменты для рассмотрения:
    • GitHub Actions: Нативный CI для GitHub с настраиваемыми рабочими процессами.
    • CircleCI: Высокомасштабируемый CI с поддержкой расширенного параллелизма.
    • Buildkite: CI, ориентированный на разработчиков, с масштабируемой инфраструктурой.

№2 Конвейер CD (`CD Pipeline`)

  • Почему это важно: Конвейеры CD автоматизируют безопасное, повторяемое развертывание программного обеспечения.
  • Инструменты для рассмотрения:
    • Argo CD: GitOps-ориентированная доставка для Kubernetes.
    • Flux: Контроллер GitOps для Kubernetes.
    • Octopus Deploy: Подходит для мультиоблачных и локальных (on-prem) сред.

№3 Оркестратор платформы (`Platform Orchestrator`)

  • Почему это важно: Инструменты оркестрации предоставляют логику для связывания рабочих процессов между различными инструментами и сервисами.
  • Инструменты для рассмотрения:
    • Humanitec: Оркестратор платформы, предоставляющий динамические среды. Является лидером рынка IDP. [internaldeveloperplatform.org](https://internaldeveloperplatform.org/)
    • Собственные решения/фреймворки: Многие команды используют общие инструменты, такие как Argo Workflows или пишут собственные скрипты на Python/Go для объединения своих процессов.
Плоскость мониторинга и логирования

№1 Наблюдаемость (`Observability`)

  • Почему это важно: Инструменты наблюдаемости обеспечивают видимость состояния, производительности и надежности приложений и инфраструктуры.
  • Инструменты для рассмотрения:
    • Prometheus: Набор инструментов для мониторинга и оповещения, особенно для Kubernetes.
    • Grafana: Инструмент для создания дашбордов, часто используемый в паре с Prometheus.
    • Datadog: Облачный мониторинг и аналитика.
Плоскость безопасности

№1 Менеджер секретов (`Secret Manager`)

  • Почему это важно: Менеджеры секретов безопасно хранят и распространяют учетные данные, ключи API и другие конфиденциальные данные.
  • Инструменты для рассмотрения:**
    • HashiCorp Vault: Ведущее в отрасли решение для управления секретами.
    • AWS Secrets Manager / Azure Key Vault / GCP Secret Manager: Решения от крупных облачных провайдеров.
    • Sealed Secrets (Bitnami): Шифрует секреты для Kubernetes.
Вывод: Строительные блоки, а не список покупок

Если из этой главы и стоит что-то вынести, так это то, что платформенная инженерия — это не выбор самых модных инструментов с полки, а подбор правильных строительных блоков для создания бесшовного опыта для разработчиков. Думайте меньше о том, «какой инструмент мне выбрать?», и больше о том, «как я могу спроектировать платформу, которая будет незаметной и мощной для моих разработчиков и принесет пользу бизнесу?»

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


7. 3 проблемы при создании IDP

Этот раздел основан на идеях Гая Менахема (Guy Menahem), архитектора решений в Amazon.

Проблема 1: Попытаться поймать всех зайцев одним выстрелом

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

Проблема 2: Оценка затрат на создание и эксплуатацию

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

Проблема 3: Создание и управление каталогом программного обеспечения

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

Наш взгляд

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

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

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

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

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


8. Ресурсы и ссылки

Сообщества

Рассылки


Ранее еще писал немного на другую тему, но про разработку и стандарты апишек,интересно, мало у кого они есть, выглядят вот так: https://gavrilov.info/all/analiz-zalando-restful-api-and-event-guidelines/

Сводная статья: Основы проектирования современного хранилища данных

Эта статья объединяет два материала из блога Apache SeaTunnel, посвященных фундаментальным принципам построения современных аналитических платформ. Мы рассмотрим перевод оригинальных текстов и затем погрузимся в детальный разбор упомянутой методологии.

Источник: Apache SeaTunnel’s Substack
Даты: 5 сентября 2025 г. и 14 сентября 2025 г.


Часть 1: Сводный перевод статей
(I) Принципы архитектуры модели данных: Четыре уровня и семь этапов, «краеугольный камень» моделирования Data Lake и хранилищ данных

Руководство по проектированию и практическому применению Data Lake и хранилищ данных (2025) состоит из четырех последовательных частей. Следуя основной линии «архитектура модели – общие спецификации – спецификации наслоения – спецификации именования», оно позволяет системно построить современное озеро данных (data lake) и хранилище, которое может развиваться, управляться и использоваться совместно.

https://substack.com/home/post/p-172756839

(II) Полное руководство по основным стандартам проектирования хранилищ данных: от уровней и типов до жизненного цикла

Руководство по проектированию и практическому применению Data Lakehouse: стандарты моделирования и именования для Data Lakehouse (2025)» состоит из четырех прогрессивных руководств, структурированных по основной линии: Архитектура модели — Общие стандарты — Стандарты наслоения — Стандарты именования. Вместе они позволяют системно построить развиваемое, управляемое и совместно используемое современное data lakehouse.

https://substack.com/home/post/p-173419940


Часть 2: Разбор методологии — от уровней до жизненного цикла

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

Основная цель — создать «развиваемое, управляемое и совместно используемое» хранилище. Это означает, что система должна быть:

  • Развиваемой: Легко адаптируемой к новым источникам данных и бизнес-требованиям без необходимости полной перестройки.
  • Управляемой: Иметь четкие правила качества данных, безопасности и контроля доступа.
  • Совместно используемой: Данные должны быть понятны и доступны для разных команд и отделов компании.

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

  1. Архитектура модели: Общий план строения хранилища.
  2. Общие спецификации: Единые правила для всей системы (например, форматы дат, стандарты кодирования).
  3. Спецификации наслоения: Правила и состав данных для каждого архитектурного уровня.
  4. Спецификации именования: Единые правила наименования таблиц, полей и других объектов для их легкой идентификации (например, `fct_` для таблиц фактов, `dim_` для измерений, `mart_` для витрин).
Четыре архитектурных уровня

Это — костяк всей системы, по которому данные движутся и преобразуются от “сырых” до готовых к анализу.

1. `ODS` (Operational Data Store — Оперативное хранилище данных)

  • Назначение: Первый слой для приема данных из различных систем-источников (базы данных сайта, CRM, ERP, мобильные приложения).
  • Состояние данных: «Сырые» или минимально обработанные данные. Их структура максимально приближена к оригиналу. Этот слой служит буфером и архивом.
  • Пример: Каждый час система автоматически копирует новые записи о заказах из базы данных интернет-магазина и данные о клиентах из CRM в отдельные таблицы в слое `ODS`. Данные хранятся “как есть”.

2. `DW` (Data Warehouse — Хранилище данных)
Это центральный и самый сложный слой, где происходит основная магия: очистка, интеграция и моделирование данных. Он делится на три подслоя:

  • `DWD` (Data Warehouse Detail — Детальный слой)
    • Назначение: Создание «единого источника правды». Данные из `ODS` очищаются, унифицируются (например, все статусы “Доставлен”, “delivered”, “Complete” приводятся к единому формату `delivered`) и связываются между собой.
    • Состояние данных: Очищенные, детализированные, исторически полные данные. Здесь хранятся все транзакции и события в их самой гранулярной форме.
    • Пример: На основе сырых данных о заказах из `ODS` создается таблица `dwd_orders`, где у каждого заказа есть уникальный идентификатор, ссылка на клиента, очищенный статус и стандартизированная дата.
  • `DWM` (Data Warehouse Middle — Промежуточный слой / Слой моделей)
    • Назначение: Агрегация и трансформация данных для бизнес-аналитики. Здесь детальные данные из `DWD` преобразуются в модели «звезда» или «снежинка», состоящие из фактов (события, транзакции) и измерений (справочники).
    • Состояние данных: Структурированные, готовые для анализа данные.
    • Пример: На основе `dwd_orders` создается таблица фактов `fct_sales` (содержащая количество, сумму, скидку) и связанные с ней таблицы-измерения: `dim_customers` (клиенты), `dim_products` (товары), `dim_calendar` (календарь).
  • `DWS` (Data Warehouse Service/Summary — Слой витрин данных)
    • Назначение: Предоставление данных конечным пользователям. Витрина — это набор данных, подготовленный для конкретного отдела или задачи.
    • Состояние данных: Предварительно агрегированные, узкоспециализированные данные.
    • Пример: Для отдела маркетинга создается витрина `mart_marketing_performance`, где продажи агрегированы по дням, рекламным кампаниям и регионам. Это позволяет маркетологам быстро оценивать эффективность своих действий, не обращаясь к сложным моделям слоя `DWM`.

3. `APP` (Application — Слой приложений)

  • Назначение: Слой визуализации и потребления данных. С ним работают конечные бизнес-пользователи.
  • Пример: BI-системы (Power BI, Tableau, Looker), которые подключаются к витринам данных в `DWS` и строят на их основе интерактивные дашборды, графики и отчеты.
Семь этапов жизненного цикла данных

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

  1. Сбор (Source): Определение и доступ к источникам данных (БД, API, файлы).
  2. Загрузка (Ingestion): Перемещение данных из источников в слой `ODS`.
  3. Хранение (Storage): Размещение сырых данных в операционном хранилище (`ODS`).
  4. Очистка и Интеграция (Cleansing & Integration): Преобразование данных и создание детального слоя (`DWD`).
  5. Моделирование (Modeling): Построение аналитических моделей (таблиц фактов и измерений) в слое `DWM`.
  6. Агрегация (Aggregation/Serving): Создание витрин данных для конкретных нужд в слое `DWS`.
  7. Визуализация и Анализ (Visualization & Analysis): Потребление данных через BI-инструменты в слое `APP`.

Итог: Создание современного хранилища данных

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

Разделение на слои решает несколько ключевых проблем:

  • Изоляция изменений: Изменение в системе-источнике повлияет только на слой `ODS`, а не на всё хранилище.
  • Надежность: Данные проходят последовательную проверку и обогащение, что повышает доверие к ним.
  • Производительность: Пользователи работают с быстрыми, предварительно агрегированными витринами данных (`DWS`), а не с огромными детализированными таблицами.

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

Искусство скорости: Руководство по оптимизации для аналитики в Data Lakehouse с DuckDB

DuckDB завоевал огромную популярность как “SQLite для аналитики”. Это невероятно быстрый, встраиваемый, колоночный движок, который не требует отдельного сервера. Однако его мощь по-настоящему раскрывается, когда он получает доступ к данным эффективно. Просто натравить DuckDB на петабайтный дата-лейк без подготовки — это рецепт для медленных запросов и высоких затрат.

Как же построить мост между огромным хранилищем данных и молниеносной интерактивной аналитикой, которую обещает DuckDB?

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

Большая картина: Подготовка данных с помощью Trino

Данные в вашем Lakehouse не появляются из ниоткуда. Они поступают из операционных баз данных, потоков событий (Kafka), логов и десятков других источников. Прежде чем DuckDB сможет их эффективно запросить, эти данные нужно собрать, очистить, трансформировать и, что самое важное, организовать в надежный и производительный формат.

Здесь на сцену выходит Trino (ранее известный как PrestoSQL).

Что такое Trino? Это мощный распределенный SQL-движок, созданный для выполнения запросов к гетерогенным источникам данных. Его суперсила — способность “на лету” объединять данные из PostgreSQL, Kafka, Hive, MySQL и многих других систем.

Роль Trino в Lakehouse: В современной архитектуре Trino часто выступает в роли “фабрики данных”. Он выполняет тяжелую работу по ETL/ELT (Extract, Transform, Load), подготавливая данные для аналитических инструментов вроде DuckDB.

Типичный сценарий использования:

  1. Источники: У вас есть события о прослушивании треков в Kafka, а информация о пользователях — в базе данных PostgreSQL.
  2. Задача: Создать единую, денормализованную таблицу Iceberg для аналитики.
  3. Решение с Trino: Вы настраиваете в Trino коннекторы к Kafka и PostgreSQL. Затем вы запускаете периодический SQL-запрос, который читает данные из обоих источников, объединяет их и записывает результат в новую или существующую таблицу Iceberg.
-- Этот запрос выполняется в Trino, а не в DuckDB!
    INSERT INTO iceberg_catalog.analytics.daily_user_activity
    SELECT
        u.user_id,
        u.country,
        e.event_timestamp,
        e.track_id,
        e.duration_ms
    FROM
        postgres_catalog.public.users u
    JOIN
        kafka_catalog.raw_data.listen_events e ON u.user_id = e.user_id
    WHERE
        e.event_date = CURRENT_DATE;

Как отмечается в одном из руководств, именно такой `INSERT INTO ... SELECT ...` является типичным способом перемещения данных в Iceberg с помощью Trino.

Итог: Trino работает “глубоко в машинном отделении” вашего Lakehouse. Он берет на себя тяжелые, распределенные задачи по преобразованию данных, а DuckDB получает на вход уже чистые, структурированные и оптимизированные для чтения таблицы Iceberg.

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

Подход 1: Табличные форматы (Iceberg) — Читайте только то, что нужно

Это самый продвинутый и рекомендуемый подход для серьезной аналитики, особенно в serverless-архитектуре.

  • Как это работает: Вместо того чтобы работать с “россыпью” файлов Parquet, вы работаете с логической таблицей, управляемой Apache Iceberg. Расширение `iceberg` в DuckDB использует метаданные Iceberg для интеллектуального отсечения ненужных файлов (partition pruning) и блоков данных (predicate pushdown), читая с диска минимально необходимый объем информации.
  • Архитектура: `Данные на S3 -> Trino (ETL) -> Таблица Iceberg -> DuckDB (Аналитика)`
Назначение и сценарии использования:
  • Serverless-аналитика: Основной кейс. AWS Lambda или Google Cloud Function, оснащенная DuckDB, выполняет SQL-запрос к озеру данных. Благодаря Iceberg, функция читает всего несколько мегабайт вместо гигабайт, что делает ее выполнение быстрым (<1 сек) и дешевым.
  • Локальная разработка и BI: Аналитик данных или инженер открывает Jupyter Notebook на своем ноутбуке. С помощью DuckDB он подключается напрямую к производственному Lakehouse и выполняет исследовательский анализ, не создавая копий данных и не перегружая кластеры.
  • Встраиваемая аналитика: Backend-сервис на Python или Node.js, которому нужно быстро отвечать на аналитические вопросы (например, “показать статистику пользователя за последний месяц”). Он использует DuckDB для прямого запроса к Lakehouse без обращения к промежуточной базе данных.

Подход 2: RPC-стриминг (Apache Arrow Flight) — Прямой канал к данным

Иногда вам не нужна вся мощь Iceberg, а нужно просто эффективно выполнить запрос на удаленном экземпляре DuckDB и получить результат.

  • Как это работает: Вы запускаете сервер, который инкапсулирует DuckDB. Клиент и сервер общаются по протоколу Arrow Flight — высокопроизводительному фреймворку для стриминга колоночных данных в формате Apache Arrow без затрат на сериализацию.
  • Архитектура: `Клиент -> Arrow Flight RPC -> Сервер с DuckDB -> Данные (любой источник)`
Назначение и сценарии использования:
  • Интерактивные дашборды: Веб-интерфейс (React, Vue) должен строить графики в реальном времени. Он отправляет SQL-запросы на Flight-сервер и получает данные для отрисовки практически мгновенно, без “тяжести” HTTP/JSON.
  • API-шлюз для данных: Централизация доступа к данным для множества внутренних микросервисов. Вместо того чтобы каждый сервис имел свои креды и логику подключения к БД, они обращаются к единому, стабильному Flight API.
  • Кросс-языковое взаимодействие: Сервис на Java должен получить результаты вычислений из BI-системы, построенной на Python и DuckDB. Arrow Flight обеспечивает эффективный и стандартизированный мост между ними.

Подход 3: “API поверх данных” (ROAPI & DataFusion) — Декларативная альтернатива

Что, если вам не нужна вся гибкость SQL, а нужен стандартный REST или GraphQL API поверх ваших данных без строчки кода? Здесь на сцену выходит ROAPI.

  • Как это работает: ROAPI — это инструмент, который автоматически создает API, читая конфигурационный YAML-файл, где вы описываете ваши данные (Parquet, CSV и т.д.). Под капотом он использует Apache Arrow DataFusion, движок запросов, написанный на Rust, являющийся идейным братом DuckDB.
  • Архитектура: `Клиент (HTTP/GraphQL) -> ROAPI Server -> Данные (файлы)`
Назначение и сценарии использования:
  • Быстрое прототипирование: Вам нужно за 5 минут предоставить команде фронтенда API для нового набора данных. Вы пишете 10 строк в YAML, запускаете ROAPI — и API готов.
  • Простые микросервисы данных: Сервис, единственная задача которого — раздавать данные из файла с поддержкой фильтрации и пагинации. ROAPI делает это из коробки, избавляя вас от написания рутинного кода на FastAPI или Express.js.
  • Дата-фиды для внешних систем: Предоставление стандартизированного API для партнерской системы, которая умеет работать с REST, но не умеет читать Parquet.

и еще немного про DuckDB

1. Читайте меньше данных (Золотое правило)
  • Используйте Iceberg: Это лучший способ.
  • Проекция колонок (`SELECT col1, col2...`): Никогда не используйте `SELECT *`.
  • Проталкивание предикатов (`WHERE`): Пишите максимально конкретные фильтры. DuckDB автоматически проталкивает их в сканеры Parquet и Iceberg. Используйте `EXPLAIN` для проверки того, что фильтры применяются на этапе сканирования.
2. Оптимизация SQL-запросов
  • Материализация промежуточных результатов: Если вы делаете несколько агрегаций над одним и тем же отфильтрованным срезом, сохраните его во временную таблицу с помощью `CREATE TEMP TABLE ... AS`.
  • Используйте `COPY` для массовой загрузки: При загрузке данных в DuckDB `COPY` на порядки быстрее, чем `INSERT`.
  • Предварительная агрегация: Для сверхбольших данных создавайте “витрины” с помощью Trino (см. выше) или DuckDB, а запросы стройте уже по ним.
3. Настройка окружения DuckDB
  • Управление памятью: `SET memory_limit = ‘1GB’;` — обязательная настройка в Lambda и контейнерах.
  • Параллелизм: `SET threads = 4;` — адаптируйте количество потоков под vCPU вашего окружения.
  • Настройка `httpfs` для S3: Настройте регион (`s3_region`), креды и включите кэширование метаданных, чтобы не перечитывать их при каждом запуске. ( Это комьюнити дополнение -cache_httpfs, см. ниже “Проблема Шторм” )

Еще вот тут можно почитать: https://duckdb.org/docs/stable/guides/performance/how_to_tune_workloads

Заключение: Какой подход выбрать?

Выбор архитектуры зависит от вашей задачи. Каждая из них занимает свою нишу в стеке современной инженерии данных.

Подход Ключевая технология Когда использовать
Табличный формат Trino (Подготовка) + DuckDB/Iceberg (Потребление) Стандарт для Lakehouse. Нужна строгая структура, надежность и максимальная производительность для аналитических SQL-запросов от различных инструментов.
RPC-стриминг DuckDB + Arrow Flight Нужен быстрый интерактивный SQL-доступ к удаленному экземпляру DuckDB, например, для дашборда или кастомного клиента.
API поверх данных ROAPI + DataFusion Нужно быстро и без кода поднять стандартный `REST`/`GraphQL` API поверх наборов данных для прототипирования или простых микросервисов.

Проблема Шторм из GET-запросов к S3

Давайте представим, что вы выполняете запрос к таблице Iceberg или просто к набору из 1000 файлов Parquet на S3:

SELECT count(*)
FROM read_parquet('s3://my-bucket/data/*.parquet')
WHERE event_type = 'click';

Чтобы выполнить этот запрос с максимальной эффективностью (с “проталкиванием предиката”), DuckDB должен сделать следующее, *прежде чем* читать основные данные:

  1. Получить список всех 1000 файлов.
  2. Для каждого из 1000 файлов прочитать его метаданные (футер). Футер Parquet-файла — это небольшой блок в конце файла, содержащий схему и, что самое важное, статистику по колонкам (min/max значения).
  3. Проанализировав футер, DuckDB понимает, может ли в этом файле вообще содержаться `event_type = ‘click’`. Если статистика говорит, что в файле есть только типы `’view’` и `’purchase’`, утка его пропустит.

Проблема в том, что для чтения футера каждого файла DuckDB должен отправить отдельный HTTP `GET` запрос с указанием диапазона байт (range request) к S3. То есть, один SQL-запрос порождает 1000+ мелких HTTP-запросов. Это может быть медленно и может быть дорого, так как в S3 вы платите за каждый `GET` запрос.

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

Решение: Комьюнити-расширение `cache_httpfs`

Для реализации постоянного, дискового кэширования в DuckDB используется специальное комьюнити-расширение `cache_httpfs`. Оно работает как “обертка” над стандартным `httpfs`.

Основная идея: Вы говорите DuckDB использовать `cache_httpfs` в качестве клиента для HTTP-запросов. Этот клиент сначала проверяет, нет ли уже нужного блока данных (например, футера Parquet-файла) в локальном кэше. Если есть — отдает его мгновенно. Если нет — идет в S3, скачивает блок, сохраняет его в кэш и отдает DuckDB.

Вот как это настроить:

Шаг 1: Установка и загрузка расширений

Вам понадобятся три расширения: `httpfs` (для работы с S3), `cache_httpfs` (для кэширования) и, если вы работаете с Iceberg, то и `iceberg`.

INSTALL httpfs;
INSTALL cache_httpfs;
LOAD httpfs;
LOAD cache_httpfs;
Шаг 2: Активация кэширующего клиента

Это ключевой шаг. Вы должны указать DuckDB использовать `cache_httpfs` для всех HTTP-операций.

SET httpfs_client = 'cached_httpfs';
Шаг 3: Настройка пути к кэшу (критически важно для Serverless)

По умолчанию `cache_httpfs` сохраняет кэш в директорию `~/.cache/duckdb/`. Это хорошо работает на локальной машине, но в serverless-окружениях (AWS Lambda, Cloud Functions) эта папка либо недоступна для записи, либо является эфемерной.

В serverless-среде единственное гарантированно доступное для записи место — это директория `/tmp`.

SET cache_httpfs_cache_path = '/tmp/duckdb_cache';

Этот кэш в `/tmp` будет “жить” между “теплыми” вызовами вашей Lambda-функции. Если одна и та же функция вызывается несколько раз подряд, второй и последующие вызовы будут использовать уже заполненный кэш, что кардинально ускорит выполнение запросов к одним и тем же данным.

Полный пример конфигурации (Python)

import duckdb

# Подключаемся к базе данных
con = duckdb.connect()

# Устанавливаем и загружаем расширения
con.execute("INSTALL httpfs;")
con.execute("INSTALL cache_httpfs;")
con.execute("LOAD httpfs;")
con.execute("LOAD cache_httpfs;")

# --- Настройка S3 и кэша ---

# 1. Настройте креды для S3 (если не используются IAM-роли)
# con.execute("SET s3_access_key_id='YOUR_KEY';")
# con.execute("SET s3_secret_access_key='YOUR_SECRET';")
con.execute("SET s3_region='us-east-1';")

# 2. Активируем кэширующий http-клиент
con.execute("SET httpfs_client = 'cached_httpfs';")

# 3. Указываем путь к директории кэша (обязательно для serverless)
con.execute("SET cache_httpfs_cache_path = '/tmp/duckdb_http_cache';")

# --- Выполняем запрос ---

# Первый запуск этого запроса будет медленнее,
# так как он заполнит кэш метаданными файлов.
result1 = con.execute("SELECT count(*) FROM 's3://my-bucket/data/*.parquet'").fetchone()
print(f"Первый запуск: {result1[0]}")

# Второй запуск будет на порядки быстрее,
# так как все метаданные будут прочитаны из локального кэша в /tmp.
result2 = con.execute("SELECT count(*) FROM 's3://my-bucket/data/*.parquet'").fetchone()
print(f"Второй запуск (с кэшем): {result2[0]}")

Сравнение: Встроенный кэш vs `cache_httpfs`

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

Параметр Встроенный кэш `httpfs` Расширение `cache_httpfs`
Тип Внутренний, в памяти Явный, на диске
Жизненный цикл Живет в рамках одного соединения (connection). При переподключении кэш пуст. Живет между сессиями и процессами. Сохраняется на диске до очистки.
Назначение Ускорение повторных запросов в одной и той же длительной сессии. Радикальное ускорение для любых повторных запросов, особенно в serverless (warm starts) и при локальной разработке.
Активация Включен по умолчанию Требует `SET httpfs_client = ‘cached_httpfs’;`
Настройка Не настраивается Настраивается путь (`cache_httpfs_cache_path`) и максимальный размер.

Для серьезной работы с данными на S3, особенно в serverless-архитектуре, использование расширения `cache_httpfs` является приятным дополнением и зачастую обязательным. Это та самая “серебряная пуля”, которая убирает узкое место в виде задержек сети и большого количества API-вызовов к облачному хранилищу.

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

pic. Krenskiy Dmitriy

Создаем Streaming Lakehouse за час: руководство по RisingWave, Lakekeeper и Trino

Вы когда-нибудь мечтали о платформе, где данные, отправленные через простой API-вызов, через секунды становятся доступны для аналитических запросов в вашем озере данных? Мечты сбываются. Эта статья — подробное, основанное на реальном опыте руководство, которое покажет, как построить современный Streaming Lakehouse с нуля.

Доки, которые пригодились:

https://github.com/risingwavelabs/risingwave/blob/main/docker/docker-compose.yml
https://github.com/lakekeeper/lakekeeper/blob/main/examples/minimal/docker-compose.yaml
https://docs.risingwave.com/iceberg/deliver-to-iceberg#rest-catalog

Наши главные герои:

  • RisingWave: Потоковая база данных, “сердце” нашего пайплайна. Она будет принимать, преобразовывать и материализовывать данные на лету.
  • Lakekeeper: Современный REST-каталог для Apache Iceberg. Наш “библиотекарь”, который знает все о структуре данных в озере.
  • Trino: Мощный движок для федеративных запросов. Наше “окно” в озеро данных для выполнения ad-hoc аналитики.

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

Глава 1: Почему RisingWave? Взгляд на альтернативы

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

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

Давайте сравним его с популярными альтернативами.

Сравнительная таблица

Критерий RisingWave Связка Debezium + Flink Apache SeaTunnel
Архитектура Единая система: хранение состояния (state) и вычисления в одном продукте. Компонентная: Debezium (CDC), Kafka (очередь), Flink (обработка), отдельное хранилище состояния. Инструмент для перемещения данных (data mover) с коннекторами.
Основная задача Создание и поддержка инкрементально обновляемых материализованных представлений. Гибкая, низкоуровневая обработка потоков общего назначения. Пакетная и потоковая синхронизация данных между разнородными источниками и приемниками.
Простота использования Очень высокая. Знание SQL — это 90% успеха. Скрывает сложность управления состоянием. Низкая. Требует экспертизы в каждом компоненте, написания кода на Java/Scala, управления состоянием. Средняя. Конфигурация через файлы, но требует понимания особенностей каждого коннектора.
Обработка данных SQL-ориентированная. `CREATE MATERIALIZED VIEW ... AS SELECT ...`. Программная. DataStream API, Table API/SQL. Позволяет писать сложную бизнес-логику. Декларативная. Определяет `source`, `transform`, `sink`. Менее гибкая для сложных трансформаций.
Поддержка SQL Первоклассная. Совместимость с PostgreSQL на уровне синтаксиса и протокола. Хорошая (Flink SQL), но не является основным интерфейсом. Ограниченная. Используется для простых трансформаций, а не для определения логики потока.
Управление состоянием Встроенное и автоматическое. Использует облачное хранилище (S3) как персистентный слой. Ручное. Требуется настраивать и управлять чекпоинтами и состоянием (например, RocksDB). Зависит от движка (Flink/Spark). Не является основной функцией самого SeaTunnel.

Выводы:

  • Связка Debezium + Flink — это невероятно мощный, но сложный “конструктор”. Он идеален для компаний с большими командами инженеров данных, которым нужна максимальная гибкость для создания кастомной логики.
  • Apache SeaTunnel — это отличный “швейцарский нож” для перемещения данных. Его сила — в огромном количестве коннекторов. Он идеален для задач ETL/ELT, когда нужно перелить данные из точки А в точку Б с минимальными трансформациями.
  • RisingWave занимает золотую середину для аналитических задач в реальном времени. Он предлагает простоту и элегантность SQL, скрывая под капотом всю сложность потоковой обработки. Если ваша цель — быстро получить свежие аналитические витрины из потоков данных, RisingWave — ваш выбор.

Глава 2: “Кексы” — фишки RisingWave, которые упрощают жизнь 🍰

Что делает RisingWave таким привлекательным на практике?

  1. PostgreSQL-совместимость: Вы можете подключиться к RisingWave любым клиентом, который “говорит” на протоколе Postgres (например, DBeaver, psql). Синтаксис SQL для создания представлений и запросов вам уже знаком.
  2. Все-в-одном для стриминга: RisingWave объединяет в себе прием данных (коннекторы), их обработку (инкрементальные вычисления) и хранение состояния. Вам не нужно разворачивать и связывать вместе Kafka, Zookeeper, Flink и RocksDB.
  3. Нативные Sink’и и Source’ы: В нашем примере мы использовали встроенный `webhook` коннектор — не нужно писать отдельный сервис для приема данных! RisingWave нативно умеет работать с Kafka/Redpanda, Kinesis, Pulsar, а также писать данные напрямую в Iceberg, Delta Lake и другие системы.
  4. Инкрементальные вычисления “под капотом”: Когда вы создаете материализованное представление, RisingWave строит план потоковой обработки. При поступлении новых данных он не пересчитывает все заново, а инкрементально обновляет результат. Это обеспечивает сверхнизкую задержку.

Глава 3: Практика: Строим наш Streaming Lakehouse шаг за шагом

Теперь перейдем к самому интересному — воссозданию нашего успешного проекта.

Этап 1: Архитектура и подготовка окружения (00:00 – 00:15)

Наша архитектура выглядит так:
`Webhook` → `RisingWave (Source → MView → Sink)` → `Lakekeeper (Catalog) + MinIO (Storage)` ← `Trino (Query)`

Мы используем два `docker-compose` файла:

  1. Для Lakekeeper и его экосистемы (Postgres, MinIO, Trino): [lakekeeper/examples/minimal](https://github.com/lakekeeper/lakekeeper/tree/main/examples/minimal).
  2. Для RisingWave и его окружения (Postgres для метаданных, MinIO для состояния, Grafana): [risingwave/docker/docker-compose.yml](https://github.com/risingwavelabs/risingwave/blob/main/docker/docker-compose.yml).

Ключевое действие: Мы запускаем оба стека, но для RisingWave вносим изменения, чтобы он мог взаимодействовать с Lakekeeper и Trino. Мы объединяем их в одну сеть, добавив в `docker-compose.yml` от RisingWave следующие строки:

# risingwave/docker/docker-compose.yml

services:
  risingwave-standalone:
    # ...
    # Открываем порт для вебхука, по умолчанию он не открыт наружу
           .....
        --webhook-listen-addr 0.0.0.0:4567 \ 
           .....
    ports:
      - "4566:4566". 
      # ... другие порты
      - "4567:4567"   # <--- Это важно для рабочего webhook 
    networks:
      - trino_network
# ... и для других сервисов, которые должны общаться с внешним стеком ...

networks:
  trino_network:
    name: minimal_iceberg_net # Имя сети из docker-compose Lakekeeper
    external: true

Важный момент: По умолчанию RisingWave не выставляет порт `4567` для вебхуков наружу. Мы добавили его в секцию `ports`, чтобы иметь возможность отправлять `curl` запросы с хост-машины.

Этап 2: Настройка каталогов (00:15 – 00:25)

“Озеро” без каталога — это просто “болото”. Lakekeeper будет нашим каталогом, а Trino — первым, кто научится им пользоваться.

  1. Создаем динамический каталог в Trino:
CREATE CATALOG risingwave USING iceberg
    WITH (
        "iceberg.catalog.type" = 'rest',
        "iceberg.rest-catalog.uri" = 'http://lakekeeper:8181/catalog',
        "iceberg.rest-catalog.warehouse" = 'demo',
        "s3.region"= 'dummy',
        "s3.path-style-access" = 'true',
        "s3.endpoint" = 'http://minio:9000',
        "fs.native-s3.enabled" = 'true'
    );
  1. Создаем “пустую” таблицу в Trino: Этот шаг создает метаданные в Lakekeeper. RisingWave будет находить эту таблицу и наполнять ее данными.
CREATE TABLE risingwave.trino_namespace.product_view_events (
       event_id varchar,
       user_id varchar,
       event_name varchar,
       product_id varchar,
       category varchar,
       price double,
       event_timestamp timestamp(6) with time zone,
       raw_data varchar
    );

Этап 3: Магия RisingWave (00:25 – 00:45) 🚀

Подключаемся к RisingWave через DBeaver (используя порт `4566` и стандартный драйвер PostgreSQL) и начинаем творить магию.

  1. Создаем источник-вебхук:
CREATE TABLE wbhtable1 (
      data JSONB
    ) WITH (
      connector = 'webhook'
    ) VALIDATE AS secure_compare(
      headers->>'authorization',
      'TEST_WEBHOOK'
    );

Эта команда создает эндпоинт, который принимает JSON и кладет его в таблицу `wbhtable1`. `VALIDATE AS` обеспечивает простую, но эффективную аутентификацию.

  1. Создаем материализованное представление:
CREATE MATERIALIZED VIEW product_view_events AS
    SELECT
      (data->>'event_id')::VARCHAR AS event_id,
      (data->>'user_id')::VARCHAR AS user_id,
      (data->>'event_name')::VARCHAR AS event_name,
      (data->'properties'->>'product_id')::VARCHAR AS product_id,
      (data->'properties'->>'category')::VARCHAR AS category,
      (data->'properties'->>'price')::DOUBLE PRECISION AS price,
      (data->>'timestamp')::TIMESTAMP WITH TIME ZONE AS event_timestamp,
      data::VARCHAR AS raw_data
    FROM wbhtable1;

Это ядро нашей логики. Мы на лету парсим входящий `JSONB`, приводим типы и создаем структурированное представление `product_view_events`, которое обновляется автоматически.

  1. Создаем синк (Sink) в Iceberg:
CREATE SINK rest_sink FROM product_view_events
    WITH (
        connector = 'iceberg',
        type = 'upsert',
        primary_key = 'event_id',
        catalog.type = 'rest',
        catalog.uri = 'http://lakekeeper:8181/catalog',
        warehouse.path = 'demo',
        database.name = 'trino_namespace',
        table.name = 'product_view_events',
        s3.endpoint = 'http://minio:9000',
        s3.path.style.access = 'true',
        s3.access.key = 'minio-root-user',
        s3.secret.key = 'minio-root-password',
        s3.region = 'dummy'
    );

“Грабли”, которые мы собрали: На пути к этому финальному запросу мы столкнулись с несколькими ошибками, которые стоили нам времени. Вот они, чтобы вы не повторяли наших ошибок:

  • `catalog.uri`: Должен указывать на полный путь к REST API каталогу, в случае Lakekeeper это `http://lakekeeper:8181/catalog`.
  • `warehouse.path`: Должен содержать логическое имя хранилища (`demo`), а не его физический путь в S3.
  • `s3.region`: Критически важный параметр! S3-клиент внутри RisingWave требует его обязательного указания, даже для MinIO. Хотя само значение (`us-east-1` или любое другое) для MinIO не принципиально, его отсутствие приводит к ошибке `region is missing` и сбою записи данных.

Этап 4: Запуск и проверка (00:45 – 01:00)

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

seq 1 100 | xargs -I {} -P 10 bash -c '
  EVENT_ID=$(uuidgen)
  USER_ID="usr_$(uuidgen | head -c 8)"
  PRODUCT_ID="prod_$(uuidgen | head -c 8)"
  TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

  curl -s -o /dev/null -X POST \
    http://localhost:4567/webhook/dev/public/wbhtable1 \
    -H "Content-Type: application/json" \
    -H "Authorization: TEST_WEBHOOK" \
    -d "{
          \"event_id\": \"$EVENT_ID\",
          \"user_id\": \"$USER_ID\",
          \"event_name\": \"product_viewed\",
          \"properties\": {
            \"product_id\": \"$PRODUCT_ID\",
            \"category\": \"electronics\",
            \"price\": 9199.99
          },
          \"timestamp\": \"$TIMESTAMP\"
        }"
'

И вот он, момент истины. Идем в DBeaver, открываем подключение к Trino и выполняем:

select * from risingwave.trino_namespace.product_view_events;

Результат перед вами:

Данные, только что сгенерированные и отправленные по HTTP, уже лежат в озере данных в формате Parquet и доступны для анализа. Ура!

Глава 4: Наблюдаемость: Смотрим на систему под нагрузкой

RisingWave поставляется с готовыми дашбордами для Grafana. Взглянем на них после нашей нагрузки.

Можно листать стрелками -->>
  • Пропускная способность (Throughput): Мы видим, как данные проходят через материализованное представление и записываются синком. Пики на графике соответствуют нашей нагрузке.
  • Задержка барьеров (Barrier Latency): Это ключевой показатель здоровья потоковой системы. Он показывает время, необходимое для создания контрольной точки (чекпоинта). Значения в десятки миллисекунд говорят о том, что система абсолютно здорова и справляется с нагрузкой без задержек.
  • Ресурсы (CPU/Memory): Графики показывают стабильное и предсказуемое потребление ресурсов.

Эти метрики доказывают, что система не просто работает, а работает стабильно и эффективно.

Заключение

Мы сделали это! Меньше чем за час мы развернули и настроили полноценный Streaming Lakehouse. Мы доказали, что современные инструменты, такие как RisingWave, могут кардинально упростить создание сложных систем обработки данных в реальном времени.

Путь от ошибки `Table does not exist` до работающего пайплайна был непростым, но каждая решенная проблема углубляла мое понимание системы. Теперь есть не просто набор инструкций, а проверенный в бою рецепт, учитывающий все “подводные камни”.

Путь к аналитике в реальном времени открыт. Хорошего стриминга и бурного потока с домом у озера, главное что бы избушку не смыло :)

UPD: Проверил еще пару штук

Создаем сурс из Кафки

CREATE SOURCE kafka_src (
  action VARCHAR
) WITH (
  connector = 'kafka',
  topic = 'query_complete',
  properties.bootstrap.server = 'broker1:29092'
);

создаем синк в другую кафку

CREATE SINK kafka_sink from kafka_src WITH (
  connector = 'kafka',
  topic = 'query_complete',
  properties.bootstrap.server = 'broker2:29092'
) FORMAT PLAIN ENCODE JSON

Еще вебхук

CREATE TABLE wbhtable2 (
      data JSONB
    ) WITH (
      connector = 'webhook'
    ) VALIDATE AS secure_compare(
      headers->>'authorization',
      'TEST_WEBHOOK'
    );

Делаем материализацию

CREATE MATERIALIZED VIEW events AS
    SELECT
      (data->>'action')::VARCHAR AS action
    FROM wbhtable2;

делаем синк из материализации в кафку

CREATE SINK kafka_sink2 FROM events WITH (
  connector = 'kafka',
  topic = 'query_complete',
  properties.bootstrap.server = 'broker2:29092'
) FORMAT PLAIN ENCODE JSON (force_append_only='true');

Без материализации сообщения прилетают так: {“data”:“{\”action\“: \”55555\“}”}
А с материализацией: {“action”:“99999”}

Пример запроса

curl -s -o /dev/null -X POST \
    http://localhost:4567/webhook/dev/public/wbhtable2 \
    -H "Content-Type: application/json" \
    -H "Authorization: TEST_WEBHOOK" \
    -d "{\"action\": \"11111\"}"

Еще про s3 подобные архитектуры: https://gavrilov.info/all/bitva-novyh-arhitektur-sravnivaem-arc-gigapi-i-ducklake/

Earlier Ctrl + ↓