NFT hackatao
Хакатао по дешевке :)
Налетай, торопись покупай живопись
Мне у хакатао медведь нравится :) оч крутой
UPD:
Ушла королева))
Welcome to my personal place for love, peace and happiness 🤖
Хакатао по дешевке :)
Налетай, торопись покупай живопись
Мне у хакатао медведь нравится :) оч крутой
UPD:
Ушла королева))
Современные системы обработки данных все чаще работают с непрерывными потоками событий — от отслеживания активности пользователей на сайтах до мониторинга 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”.
В потоковой обработке отсутствие состояния также означает, что система выполняет только простые операции преобразования или фильтрации (в SQL-терминах это `SELECT` и `WHERE`). Сложные операции, требующие группировки или объединения данных (`GROUP BY`, `JOIN`, `ORDER BY`), в таких системах невозможны.
Преимущества stateless-систем:
Если ваши задачи укладываются в эти ограничения (нет агрегаций, нет необходимости группировать данные), вам следует использовать stateless-обработку. Часто для таких задач даже не нужен специализированный движок потоковой обработки — достаточно сервиса, который читает события из источника (например, Apache Kafka), выполняет простую логику и записывает результат.
Примеры использования:
Пример простого SQL-запроса, который может быть выполнен в stateless-системе:
SELECT timestamp, redact(log_text) -- Выбираем время и скрываем часть текста лога
FROM logs
WHERE log_level = 'ERROR'; -- Только для событий с уровнем 'ERROR'Однако большинство бизнес-задач требуют запоминания информации о прошлых событиях, то есть требуют наличия состояния 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). Оно необходимо для любого запроса, который вычисляет агрегаты по времени.
Состояние полезно даже в задачах, которые на первый взгляд кажутся простыми. Например, при загрузке событий в озер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) с локальным кэшем | Современный подход, при котором основное хранилище состояния отделено от вычислений. На вычислительных узлах находится только “горячий” кэш активных данных. Это значительно ускоряет масштабирование и восстановление после сбоев, так как не нужно перемещать терабайты данных между узлами. |
Теперь, когда наши узлы хранят состояние, что произойдет, если они выйдут из строя? Если не принять мер, состояние будет потеряно.
Для обеспечения отказоустойчивости 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 — Backstage. Большинство других популярных решений, таких как Port, являются коммерческими (SaaS) продуктами, хотя они и могут предлагать open source компоненты для интеграции https://internaldeveloperplatform.org/developer-portals/port/
Поэтому основной фокус в open source сегменте приходится именно на Backstage, который был создан в Spotify и позже передан в Cloud Native Computing Foundation (CNCF).
Backstage — это не готовый продукт, а фреймворк для создания собственного портала разработчика https://cloudomation.com/cloudomation-blog/5-internal-developer-portals-and-what-software-engineers-say-about-them/. Это его главное преимущество и одновременно главный недостаток. Он предоставляет базовые строительные блоки и архитектуру, на основе которых компании могут построить портал, идеально соответствующий их процессам и инструментам.
Кстати очень интересная статья про порталы, платформы и их различия.
Cloudomation Guide – Building Internal Developer Platforms.pdf есть еще гайд обобщенный. А основная концепция конечно тут https://internaldeveloperplatform.org
Основные компоненты Backstage:
Поскольку настоящий open source конкурент у Backstage практически отсутствует, наиболее корректно сравнить его не с другим open source решением, а с подходом использования коммерческих SaaS-платформ, ярким представителем которых является 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” (покупать).
Выбирайте `Backstage`, если:
Рассмотрите коммерческие решения (типа Port), если:
Вне зависимости от выбора, начинать следует с определения ключевых проблем разработчиков, которые должен решить портал. Инструмент — это лишь средство для достижения цели, будь то упрощение создания новых сервисов, централизация знаний или автоматизация рутинных задач.
Ниже небольшой гайд на основе дока выше Cloudomation Guide – Building Internal Developer Platforms.pdf
***
Ниже представлен обзор внутренних платформ для разработчиков (Internal Developer Platforms, или IDP). Поскольку инженерные команды сталкиваются с растущей сложностью, IDP становятся решением для снижения разногласий между разработкой и эксплуатацией.
Независимо от того, оцениваете ли вы готовые платформы или создаете собственное решение, этот документ предлагает ценные сведения и тщательно подобранные ресурсы, которые помогут вам эффективно пройти путь внедрения IDP.
Основные тезисы:
***
Внутренние платформы для разработчиков (IDP) лежат в основе дисциплины платформенной инженерии (Platform Engineering).
Пояснение:
Внутренняя платформа для разработчиков — это, по сути, продукт, предназначенный для разработчиков внутри организации. Она предоставляет им доступ по принципу самообслуживания к технической инфраструктуре и рабочим процессам, таким как конвейеры развертывания или облачные ресурсы. пост на dev.to. Ключевая идея — относиться к своей внутренней платформе как к продукту, а к разработчикам — как к клиентам. еще пост с dev.to. Это позволяет им не ждать выполнения заявок в отдел эксплуатации и не нести полную ответственность за инфраструктуру, как в модели «you build it, you run it».
IDP призваны решить вечную проблему, которая преследует всех разработчиков ПО: программное обеспечение чрезвычайно сложно, и ни один человек не может знать всего, что требуется для создания целого программного продукта.
На схеме ниже показаны ключевые концепции, лежащие в основе IDP.
IDP предоставляют функции, которые являются центральными в повседневной работе разработчиков программного обеспечения.
Это лишь примеры функций, которые может иметь IDP. Каждая IDP уникальна для организации, которая ее использует. Часто они создаются с нуля или сильно кастомизируются под нужды компании.
По мере усложнения процесса поставки ПО организации сталкиваются с фрагментированными практиками DevOps, несогласованными рабочими процессами и операционной неэффективностью. От разработчиков ожидают, что они будут управлять инфраструктурой, конвейерами CI/CD, политиками безопасности и мониторингом, что часто приводит к когнитивной перегрузке и снижению производительности. Именно здесь на помощь приходят платформенная инженерия и IDP.
Каждая IDP уникальна, но есть некоторые общие характеристики, присущие большинству из них. В самом простом виде каждая IDP состоит примерно из трех «частей»:
Следующая диаграмма архитектуры, основанная на модели CNOE (Cloud Native Operational Excellence), дает более детальное представление.
В этой диаграмме «Портал разработчика» (`Developer Portal`) является фронтендом IDP. Компонент «Оркестрация рабочих процессов» (`Workflow Orchestration`) будет бэкендом.
Ниже приведен более подробный пример архитектуры, показывающий, какие типы инструментов и сервисов могут быть частью IDP, сгруппированные по функциональным уровням (плоскостям).
Основная идея IDP — объединить инструменты, сервисы, конфигурации и другую информацию в одном месте. Инженеры-программисты, а также другие заинтересованные стороны (например, команды эксплуатации) должны иметь возможность использовать IDP как единую точку входа для обнаружения и взаимодействия с приложениями и инфраструктурой компании.
Таким образом, бэкенд IDP, как правило, должен быть сильным в двух типах функциональности: №1 Интеграция и №2 Автоматизация.
По мере того как организации масштабируют и модернизируют поставку своего программного обеспечения, сложность управления инфраструктурой, рабочими процессами разработчиков и управлением (governance) растет экспоненциально.
Внутренняя платформа для разработчиков (IDP) предлагает стратегический ответ на этот вызов, обеспечивая более быструю доставку, более сильное управление и снижение операционных рисков. Однако, чтобы получить одобрение руководства, крайне важно сформулировать преимущества IDP в терминах бизнеса.
Вот как можно обосновать необходимость IDP, обращаясь к четырем ключевым проблемам руководителей: Масштаб, Затраты, Риски и Управление.
*(В оригинальном документе здесь показаны два слайда из презентации PlatformCon23, представляющие “текущее состояние” и “будущее состояние”. Текущее состояние показывает, как команда из 50 разработчиков приложений вынуждена вручную взаимодействовать с разрозненным набором инструментов. Будущее состояние показывает, как команда платформы предоставляет единый, унифицированный слой, который абстрагирует эту сложность, позволяя командам приложений работать более эффективно.)*
Обратите внимание сколько кубиков вверху, а сколько внизу. В России кстати очень быстро вырывается вперед разработка на фреймворках streamlit, они почти ничего не делают повторно, если развернули хоть раз его с авторизацией и ипишками – в основном только ui колбасят. Но часто такие инициативы не вырастают сильно, их обычно давят в зародыше, так как они не соответствуют общему формату и не хотят делать все остальные кубики или не умеют – в общем похожи они на shadow it. Но если же им каким, то образом это удалось, то потом их не остановить и придя к ним через год, можно увидел второй прод, полностью зеркальный :) и сделал его кто-то один вечерами.
Ключевым фактором для вашего бизнес-обоснования являются данные. Проведите опрос в вашей инженерной организации, чтобы собрать информацию, например, о времени, затрачиваемом на инфраструктурные задачи по сравнению с разработкой новой функциональности.
Итоговые мысли: Что не дает спать руководителям?
При формировании своего предложения обращайтесь непосредственно к рискам и результатам, которые больше всего волнуют ваших руководителей. Например:
Внутренняя платформа для разработчиков — это не просто технический инструмент, это стратегический актив. С правильной постановкой вопроса, данными и видением вы можете продемонстрировать, как хорошо реализованная IDP поддерживает не только инженерию, но и весь бизнес.
Этот раздел основан на идеях, вдохновленных видео Виктора Фарчича «От нуля до полностью работающей платформы для разработчиков за 5 шагов!». Он описывает не столько шаги, сколько ключевые возможности, которые должна иметь IDP, чтобы быть полезной.
5 ключевых возможностей IDP (по версии Виктора Фарчича):
Наш взгляд на ключевые возможности (немного измененный и дополненный):
Если вы подумаете о проблемах, с которыми вы недавно сталкивались как инженер платформы или DevOps-инженер, вы, вероятно, сможете соотнести их с одной из описанных возможностей.
Некоторые примеры:
Цель и ценность этих ключевых возможностей — помочь вам понять, почему вы продолжаете терпеть неудачи в некоторых вопросах, и как вы можете начать исправлять ситуацию таким образом, чтобы это было долговечно и устойчиво управляемо.
В этой статье рассматривается, как структурировать IDP, с разбивкой по ключевым компонентам и с примерами инструментов, которые вы можете использовать.
Мы классифицируем эти инструменты, используя «референсную архитектуру», популяризированную `platformengineering.org`. Эта структура разбивает экосистему на пять основных компонентов, известных как «плоскости» (`planes`):
Вот разбивка инструментов, которые вы могли бы использовать для создания IDP. Важное замечание: существует множество доступных инструментов. Упомянутые здесь — лишь примеры.
№1 Портал разработчика (`Developer Portal`)
№2 Облачные среды разработки (`Cloud Development Environments, CDEs`)
№1 Конвейер CI (`CI Pipeline`)
№2 Конвейер CD (`CD Pipeline`)
№3 Оркестратор платформы (`Platform Orchestrator`)
№1 Наблюдаемость (`Observability`)
№1 Менеджер секретов (`Secret Manager`)
Если из этой главы и стоит что-то вынести, так это то, что платформенная инженерия — это не выбор самых модных инструментов с полки, а подбор правильных строительных блоков для создания бесшовного опыта для разработчиков. Думайте меньше о том, «какой инструмент мне выбрать?», и больше о том, «как я могу спроектировать платформу, которая будет незаметной и мощной для моих разработчиков и принесет пользу бизнесу?»
Настоящая магия происходит тогда, когда эти инструменты перестают быть отдельными частями пазла и становятся частью целостной платформы для разработчиков, где разработчики едва замечают лежащую в основе сложность, потому что платформа работает с ними, а не против них.
Этот раздел основан на идеях Гая Менахема (Guy Menahem), архитектора решений в Amazon.
Проблема 1: Попытаться поймать всех зайцев одним выстрелом
Многие команды платформенной инженерии пытаются сделать все сразу и в итоге не достигают ничего. Объединение всех инструментов в единое решение может привести к тому, что вы упустите основной рабочий процесс пользователя, что приведет к отказу от платформы. Вместо этого оттачивайте свои продуктовые навыки, чтобы понять, какую пользу пользователи извлекут из платформы, даже если на начальном этапе она будет включать всего несколько инструментов.
Проблема 2: Оценка затрат на создание и эксплуатацию
Создание ценной платформы требует ресурсов, включая выделенную команду платформенной инженерии, бюджет на облачную инфраструктуру и сотрудничество. Также необходимо учитывать операционные расходы, такие как обновления и патчи безопасности. Оценивайте ресурсы, определяя размер и продолжительность работы команды, сосредотачиваясь на минимально жизнеспособном продукте (MVP) и рассчитывая облачные и операционные затраты.
Проблема 3: Создание и управление каталогом программного обеспечения
Управление каталогом программного обеспечения, который представляет собой сложную базу данных ПО, систем и документации, может быть непростой задачей. Вовлечение всех команд в обновление и поддержание каталога имеет решающее значение для его качества и принятия. Упростите управление каталогом, автоматизировав сбор информации, принудительно обновляя его в процессах CI/CD и поощряя ежедневное использование платформы.
Проблемы, которые описывает Гай, реальны. Однако одна фундаментальная истина, которую он не упоминает, заключается в том, что большинство проблем при создании IDP не являются техническими.
Вместо этого наиболее распространенные проблемы возникают из-за недостатка коммуникации между людьми. Это типично для многих инженерных инициатив, поскольку инженеры, как правило, имеют очень специфический взгляд на инструменты, которые они создают, и этот взгляд часто сильно отличается от точки зрения их пользователей.
То же самое часто происходит и в командах платформенной инженерии: они могут создавать ценную автоматизацию и сервисы, но если их нелегко использовать, в них отсутствуют ключевые функции, необходимые инженерам-программистам, или они просто не решают самые большие проблемы, с которыми сталкиваются разработчики, то они просто не будут использовать IDP.
Самое важное, что вы должны делать как инженер платформы, — регулярно спрашивать своих инженеров-программистов! Просите их протестировать то, что вы создаете, сказать, полезно ли это для них, и если ответ «нет», то изменяйте то, что вы создаете, чтобы ваши инженеры-программисты захотели это использовать.
В конце концов, в этом и заключается вся суть IDP: она должна быть полезной для инженеров-программистов.
Сообщества
Рассылки
Ранее еще писал немного на другую тему, но про разработку и стандарты апишек,интересно, мало у кого они есть, выглядят вот так: https://gavrilov.info/all/analiz-zalando-restful-api-and-event-guidelines/
Эта статья объединяет два материала из блога Apache SeaTunnel, посвященных фундаментальным принципам построения современных аналитических платформ. Мы рассмотрим перевод оригинальных текстов и затем погрузимся в детальный разбор упомянутой методологии.
Источник: Apache SeaTunnel’s Substack
Даты: 5 сентября 2025 г. и 14 сентября 2025 г.
Руководство по проектированию и практическому применению Data Lake и хранилищ данных (2025) состоит из четырех последовательных частей. Следуя основной линии «архитектура модели – общие спецификации – спецификации наслоения – спецификации именования», оно позволяет системно построить современное озеро данных (data lake) и хранилище, которое может развиваться, управляться и использоваться совместно.
https://substack.com/home/post/p-172756839
Руководство по проектированию и практическому применению Data Lakehouse: стандарты моделирования и именования для Data Lakehouse (2025)» состоит из четырех прогрессивных руководств, структурированных по основной линии: Архитектура модели — Общие стандарты — Стандарты наслоения — Стандарты именования. Вместе они позволяют системно построить развиваемое, управляемое и совместно используемое современное data lakehouse.
https://substack.com/home/post/p-173419940
Статьи описывают структурированный подход к созданию современных аналитических систем. Эта методология основана на нескольких ключевых концепциях, которые мы разберем подробно.
Основная цель — создать «развиваемое, управляемое и совместно используемое» хранилище. Это означает, что система должна быть:
Основой для этого служит подход, который статьи называют «основной линией»:
Это — костяк всей системы, по которому данные движутся и преобразуются от “сырых” до готовых к анализу.
1. `ODS` (Operational Data Store — Оперативное хранилище данных)
2. `DW` (Data Warehouse — Хранилище данных)
Это центральный и самый сложный слой, где происходит основная магия: очистка, интеграция и моделирование данных. Он делится на три подслоя:
3. `APP` (Application — Слой приложений)
Хотя в статьях этапы не расшифровываются, они логически вытекают из описанной архитектуры и представляют собой полный путь данных от источника до пользователя.
Представленная методология — это не просто техническая инструкция, а фундаментальная философия управления данными. В мире, где данные часто хаотичны и разрозненны, такой структурированный подход позволяет навести порядок.
Разделение на слои решает несколько ключевых проблем:
Таким образом, следование принципам четырех уровней и семи этапов позволяет построить не просто базу данных, а надежную, масштабируемую и понятную аналитическую платформу, которая становится настоящим «краеугольным камнем» для принятия решений на основе данных в любой современной компании.
DuckDB завоевал огромную популярность как “SQLite для аналитики”. Это невероятно быстрый, встраиваемый, колоночный движок, который не требует отдельного сервера. Однако его мощь по-настоящему раскрывается, когда он получает доступ к данным эффективно. Просто натравить DuckDB на петабайтный дата-лейк без подготовки — это рецепт для медленных запросов и высоких затрат.
Как же построить мост между огромным хранилищем данных и молниеносной интерактивной аналитикой, которую обещает DuckDB?
В этой статье рассмотрим три фундаментальных архитектурных подхода к организации доступа к данным для DuckDB. Но прежде чем мы погрузимся в то, как *читать* данные, давайте поговорим о том, как их *готовить*.
Данные в вашем Lakehouse не появляются из ниоткуда. Они поступают из операционных баз данных, потоков событий (Kafka), логов и десятков других источников. Прежде чем DuckDB сможет их эффективно запросить, эти данные нужно собрать, очистить, трансформировать и, что самое важное, организовать в надежный и производительный формат.
Здесь на сцену выходит Trino (ранее известный как PrestoSQL).
Что такое Trino? Это мощный распределенный SQL-движок, созданный для выполнения запросов к гетерогенным источникам данных. Его суперсила — способность “на лету” объединять данные из PostgreSQL, Kafka, Hive, MySQL и многих других систем.
Роль Trino в Lakehouse: В современной архитектуре Trino часто выступает в роли “фабрики данных”. Он выполняет тяжелую работу по ETL/ELT (Extract, Transform, Load), подготавливая данные для аналитических инструментов вроде DuckDB.
Типичный сценарий использования:
-- Этот запрос выполняется в 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.
Теперь, когда данные готовы, давайте рассмотрим, как их лучше всего потреблять.
Это самый продвинутый и рекомендуемый подход для серьезной аналитики, особенно в serverless-архитектуре.
Иногда вам не нужна вся мощь Iceberg, а нужно просто эффективно выполнить запрос на удаленном экземпляре DuckDB и получить результат.
Что, если вам не нужна вся гибкость SQL, а нужен стандартный REST или GraphQL API поверх ваших данных без строчки кода? Здесь на сцену выходит ROAPI.
Еще вот тут можно почитать: 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 поверх наборов данных для прототипирования или простых микросервисов. |
Давайте представим, что вы выполняете запрос к таблице Iceberg или просто к набору из 1000 файлов Parquet на S3:
SELECT count(*)
FROM read_parquet('s3://my-bucket/data/*.parquet')
WHERE event_type = 'click';Чтобы выполнить этот запрос с максимальной эффективностью (с “проталкиванием предиката”), DuckDB должен сделать следующее, *прежде чем* читать основные данные:
Проблема в том, что для чтения футера каждого файла DuckDB должен отправить отдельный HTTP `GET` запрос с указанием диапазона байт (range request) к S3. То есть, один SQL-запрос порождает 1000+ мелких HTTP-запросов. Это может быть медленно и может быть дорого, так как в S3 вы платите за каждый `GET` запрос.
Кэширование метаданных решает именно эту проблему: оно сохраняет результаты этих мелких запросов на локальный диск, чтобы при повторном обращении к тем же файлам DuckDB брал их из локального кэша, а не летел снова в S3.
Для реализации постоянного, дискового кэширования в DuckDB используется специальное комьюнити-расширение `cache_httpfs`. Оно работает как “обертка” над стандартным `httpfs`.
Основная идея: Вы говорите DuckDB использовать `cache_httpfs` в качестве клиента для HTTP-запросов. Этот клиент сначала проверяет, нет ли уже нужного блока данных (например, футера Parquet-файла) в локальном кэше. Если есть — отдает его мгновенно. Если нет — идет в S3, скачивает блок, сохраняет его в кэш и отдает DuckDB.
Вот как это настроить:
Вам понадобятся три расширения: `httpfs` (для работы с S3), `cache_httpfs` (для кэширования) и, если вы работаете с Iceberg, то и `iceberg`.
INSTALL httpfs;
INSTALL cache_httpfs;
LOAD httpfs;
LOAD cache_httpfs;Это ключевой шаг. Вы должны указать DuckDB использовать `cache_httpfs` для всех HTTP-операций.
SET httpfs_client = 'cached_httpfs';По умолчанию `cache_httpfs` сохраняет кэш в директорию `~/.cache/duckdb/`. Это хорошо работает на локальной машине, но в serverless-окружениях (AWS Lambda, Cloud Functions) эта папка либо недоступна для записи, либо является эфемерной.
В serverless-среде единственное гарантированно доступное для записи место — это директория `/tmp`.
SET cache_httpfs_cache_path = '/tmp/duckdb_cache';Этот кэш в `/tmp` будет “жить” между “теплыми” вызовами вашей Lambda-функции. Если одна и та же функция вызывается несколько раз подряд, второй и последующие вызовы будут использовать уже заполненный кэш, что кардинально ускорит выполнение запросов к одним и тем же данным.
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]}")Стоит отметить, что стандартный `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, современный стек данных предлагает невероятную гибкость и производительность. Выбрав правильный инструмент или их комбинацию для каждой задачи, можно построить по-настоящему эффективную и масштабируемую аналитическую платформу.
Вы когда-нибудь мечтали о платформе, где данные, отправленные через простой 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
Наши главные герои:
Мы пройдем весь путь: от сравнения технологий и настройки окружения до отправки данных и любования результатами на дашбордах Grafana. И самое главное — мы поделимся всеми “граблями”, на которые наступили, чтобы вы могли их обойти.
На рынке потоковой обработки есть много инструментов, но все они предлагают разные подходы. Почему для нашей задачи мы выбрали именно 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. |
Выводы:
Что делает RisingWave таким привлекательным на практике?
Теперь перейдем к самому интересному — воссозданию нашего успешного проекта.
Наша архитектура выглядит так:
`Webhook` → `RisingWave (Source → MView → Sink)` → `Lakekeeper (Catalog) + MinIO (Storage)` ← `Trino (Query)`
Мы используем два `docker-compose` файла:
Ключевое действие: Мы запускаем оба стека, но для 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` запросы с хост-машины.
“Озеро” без каталога — это просто “болото”. Lakekeeper будет нашим каталогом, а 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'
);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
);Подключаемся к RisingWave через DBeaver (используя порт `4566` и стандартный драйвер PostgreSQL) и начинаем творить магию.
CREATE TABLE wbhtable1 (
data JSONB
) WITH (
connector = 'webhook'
) VALIDATE AS secure_compare(
headers->>'authorization',
'TEST_WEBHOOK'
);Эта команда создает эндпоинт, который принимает JSON и кладет его в таблицу `wbhtable1`. `VALIDATE AS` обеспечивает простую, но эффективную аутентификацию.
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`, которое обновляется автоматически.
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'
);“Грабли”, которые мы собрали: На пути к этому финальному запросу мы столкнулись с несколькими ошибками, которые стоили нам времени. Вот они, чтобы вы не повторяли наших ошибок:
Время накормить нашу систему данными! Запускаем в терминале скрипт для генерации и отправки 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 и доступны для анализа. Ура!
RisingWave поставляется с готовыми дашбордами для Grafana. Взглянем на них после нашей нагрузки.
Эти метрики доказывают, что система не просто работает, а работает стабильно и эффективно.
Мы сделали это! Меньше чем за час мы развернули и настроили полноценный 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/
-- 0. устанавливаем последнюю версию risingwave ( 2.6.1 )
-- 1 Создаем вебхук
CREATE TABLE wbhtable5 (
data JSONB
) WITH (
connector = 'webhook'
) VALIDATE AS secure_compare(
headers->>'authorization',
'TEST_WEBHOOK'
);
-- 2 Создаем материализацию
CREATE MATERIALIZED VIEW product_view_events5 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 wbhtable5;
-- 3 создаем подключение к iceberg
CREATE CONNECTION my_iceberg_conn5 WITH (
type = 'iceberg',
warehouse.path = 'risi', -- s3://my-bucket/warehouse/
-- database.name = 'risi_space', оказалось не нужна
s3.region = 'dummy',
s3.access.key = 'ЧЧЧ', -- Ваши ключи
s3.secret.key = 'ЧЧЧ', -- Ваши ключи
catalog.type = 'rest',
s3.endpoint = 'https://gateway.storjshare.io',
s3.path.style.access = 'true',
-- ИСПОЛЬЗУЕМ ИМЯ СЕРВИСА И ЕГО ВНУТРЕННИЙ ПОРТ!
catalog.uri = 'http://lakekeeper:8181/catalog'
)
-- 4 Устанавливаем его по умолчанию
SET iceberg_engine_connection = 'public.my_iceberg_conn5';
-- Создаем таблицу ( обязательно с ключами )
CREATE TABLE public.my_iceberg_table5 (
event_id VARCHAR PRIMARY KEY,
user_id varchar,
event_name varchar,
product_id varchar,
category varchar,
price double,
event_timestamp Timestamptz,
raw_data varchar
) ENGINE = iceberg;
-- 5 создаем синк
CREATE SINK to_sales_events5 INTO my_iceberg_table5 AS
SELECT * FROM product_view_events5;
--- Тут можно curl запустить
seq 1 10 | 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/wbhtable5 \
-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\"
}"
'
-- 6 проверяем
SELECT * FROM product_view_events5;
-- 7 проверяем ( появляются не сразу )
select * from my_iceberg_table5
И в keeper она есть
И на S3
В экосистеме разработки на macOS и Linux постоянно появляются инструменты, призванные упростить и ускорить рабочие процессы. Один из таких инструментов, быстро набравший популярность — Lima. Изначально созданный как простой способ запускать Linux на Mac, Lima превратился в мощное и гибкое решение для управления виртуальными машинами, с особым фокусом на контейнеризацию.
В этой статье мы разберем, что такое Lima, для чего он нужен, сравним его с аналогами, раскроем полезные трюки и фишки, а также проанализируем, как и когда его стоит использовать в связке с Podman.
Не большой бонус от Kimi 2.0: lima от kimi 2.0
А вот полный отчет в режиме Research: Lima анализ от kimi 2.0.pdf
Lima — это утилита командной строки (CLI), которая упрощает создание и управление Linux-виртуальными машинами, преимущественно на macOS, но также и на Linux. Его основная философия — минимализм и ориентация на разработчика signup.omerxx.com. Lima не навязывает громоздкие графические интерфейсы, а предоставляет простой и понятный CLI, который “не мешает работать”.
Основные сценарии использования Lima:
| Критерий | Lima | Docker Desktop (на macOS) | Vagrant | Multipass |
| Философия | Легковесный CLI-инструмент для запуска Linux VM с фокусом на контейнеры. | Комплексный продукт с GUI для управления контейнерами. | Универсальный менеджер VM для создания воспроизводимых сред. | Быстрый запуск VM с Ubuntu, разрабатываемый Canonical. |
| Лицензия | Open Source (MIT) | Коммерческая для крупных компаний. | Open Source (MIT) | Open Source (GPLv3) |
| Производительность | Высокая, особенно с `virtiofs` и `vz`. Низкое потребление ресурсов. | Более ресурсоемкий, особенно GUI и фоновые процессы. | Зависит от провайдера, часто более медленный запуск. | Оптимизирована для Ubuntu, производительность хорошая. |
| Гибкость | Очень высокая. Настройка через YAML, поддержка любых дистрибутивов. | Ограниченная. Вы привязаны к VM от Docker. | Высокая. Поддержка разных провайдеров (VirtualBox, VMware). | Ограниченная. В основном ориентирован на Ubuntu. |
| Простота | Просто начать, но требует понимания CLI и YAML для кастомизации. | Очень просто для новичков благодаря GUI. | Требует изучения `Vagrantfile` (Ruby). | Очень простой CLI для базовых задач. |
| Интеграция | Отличная интеграция с хост-системой (файлы, порты), но требует ручной настройки. | Глубокая, бесшовная интеграция “из коробки”. | Хорошая, но настройка может быть сложной. | Простая, но менее гибкая интеграция. |
Lima vs. Docker Desktop — это главное сравнение для пользователей macOS. Lima выигрывает в производительности, гибкости и отсутствии лицензионных ограничений. Docker Desktop предлагает удобство “всё в одном” и графический интерфейс, что может быть предпочтительнее для новичков или в корпоративных средах, где стандартизирован один инструмент.
Вся мощь Lima раскрывается через его декларативный файл конфигурации `lima.yaml`. Вот несколько ключевых возможностей, которые стоит использовать.
Вместо создания `YAML`-файла с нуля, можно использовать готовые шаблоны. Это самый быстрый способ начать работу.
limactl start template://dockerlimactl start template://podmanlimactl start template://archlinuxНа macOS с Apple Silicon (M1/M2/M3) Lima может использовать нативный фреймворк виртуализации от Apple вместо QEMU. Это значительно снижает нагрузку на CPU и повышает производительность code.saghul.net.
Для этого в вашем `lima.yaml` укажите:
vmType: "vz"Для файловой системы также рекомендуется использовать `virtiofs` для лучшей производительности.
mountType: "virtiofs"Lima позволяет монтировать директории с хост-машины в VM. Вы можете указать, какие папки монтировать и доступны ли они для записи.
mounts:
- location: "~"
writable: false
- location: "~/projects"
writable: trueЭто позволяет редактировать код в любимом редакторе на macOS, а собирать и запускать его внутри Linux VM.
Чтобы получить доступ к сервису, запущенному внутри VM, можно пробросить порты.
portForwards:
# Пробросить порт 8080 из гостевой VM на порт 8080 хоста
- guestPort: 8080
hostPort: 8080
# Можно также указать конкретный IP
- guestPort: 8888
hostIP: "127.0.0.1"Это одна из самых мощных функций. Вы можете выполнять скрипты при первом создании VM (`mode: system`) или при каждом её запуске (`mode: user`).
provision:
- mode: system
script: |
#!/bin/bash
apt-get update
apt-get install -y htop vim fish
- mode: user
script: |
#!/bin/bash
echo "Welcome back to Lima!"Это позволяет полностью автоматизировать настройку вашего рабочего окружения.
Этот вопрос часто возникает у разработчиков. Podman — это альтернатива Docker для работы с контейнерами без демона. На Linux он работает нативно. На macOS ему, как и Docker, нужна Linux-виртуальная машина.
`podman machine` — это встроенная в Podman команда, которая автоматически создает и управляет такой VM. Так зачем же здесь Lima?
Случай 1: Когда достаточно `podman machine`
Если вам просто нужна замена Docker с синтаксисом Podman и вы довольны стандартной VM (основанной на Fedora CoreOS), то `podman machine init` и `podman machine start` — это всё, что вам нужно. Это простое, интегрированное решение.
Случай 2: Когда нужна связка Lima + Podman
Связка Lima и Podman даёт контроль и гибкость. Вы используете Lima для создания и управления VM, а Podman-клиент на macOS настраиваете для работы с Podman-сервисом внутри этой VM.
Это необходимо, когда:
Как это работает на практике?
Итог по связке: Lima и `podman machine` не являются прямыми конкурентами. `podman machine` — это простое решение “под ключ”. Lima — это мощный бэкенд, который может служить основой для Podman, когда стандартных возможностей `podman machine` недостаточно.
Lima зарекомендовал себя как незаменимый инструмент для разработчиков на macOS и Linux. Он успешно занял нишу между тяжеловесными решениями вроде Vagrant и монолитными продуктами, как Docker Desktop.
Ключевые выводы:
Если вы разработчик, который ценит контроль, производительность и предпочитает работать в командной строке, Lima определенно заслуживает вашего внимания. Это мощный мост в мир Linux, встроенный прямо в ваш терминал.
В мире облачных технологий Kubernetes стал де-факто стандартом для оркестрации контейнеров. Однако его сложность является серьезным барьером для многих команд разработчиков. Платформа Rainbond ставит своей целью решить эту проблему, предлагая высокоуровневую абстракцию для управления приложениями, которая скрывает сложности Kubernetes, позволяя разработчикам сосредоточиться на коде и бизнес-логике.
Rainbond — это облачная платформа для управления приложениями (Cloud-Native Application Management Platform) с открытым исходным кодом github.com. Её ключевая философия — “ориентация на приложение” (`application-centric`). Вместо того чтобы заставлять пользователей разбираться в тонкостях `Pods`, `Deployments`, `Services` и YAML-файлов, Rainbond предлагает интуитивно понятный интерфейс и автоматизированные процессы для всего жизненного цикла приложения rainbond.cn.
Одна из главных особенностей платформы — “неинвазивная” (non-invasive) технология. Это означает, что для развертывания существующих традиционных приложений в облачной среде их не нужно переписывать или кардинально изменять. Rainbond умеет:
Основная цель Rainbond — снизить порог входа в облачные технологии и автоматизировать управление приложениями (https://rainbond.cn/docs/quick-start/architecture/design-concept rainbond.cn)). Платформа решает проблемы, которые возникают у команд, желающих использовать преимущества облака, но не имеющих достаточной экспертизы в Kubernetes.
Rainbond охватывает весь жизненный цикл приложения:
Фактически, Rainbond предоставляет опыт, похожий на PaaS (Platform as a Service), но разворачиваемый на вашей собственной инфраструктуре.
Rainbond находится на стыке нескольких категорий продуктов. Его можно сравнивать как с “чистым” Kubernetes, так и с другими PaaS-платформами.
| Платформа | Основная концепция | Сложность | Целевая аудитория |
| Rainbond | PaaS-подобная платформа поверх Kubernetes. Абстрагирует сложность, ориентирована на приложение. | Низкая | Разработчики, DevOps-инженеры, SMB, отделы, ищущие простоту. |
| Kubernetes (ванильный) | Оркестратор контейнеров. Мощный и гибкий, но требует глубоких знаний инфраструктуры. | Высокая | Опытные DevOps/SRE-инженеры, крупные компании с выделенными командами. |
| Red Hat OpenShift | Enterprise-дистрибутив Kubernetes. Добавляет множество инструментов для разработчиков и безопасности. | Средняя / Высокая | Крупные предприятия, которым нужна поддержка и расширенные функции. |
| Heroku | Управляемая PaaS. Максимальная простота развертывания, но меньше гибкости и привязка к вендору. | Очень низкая | Стартапы, разработчики, которым нужно быстро запустить проект без администрирования. |
| CapRover / Dokku | Self-hosted PaaS. Открытые проекты, похожие на Heroku, но для развертывания на своих серверах. | Низкая / Средняя | Индивидуальные разработчики, небольшие команды. |
Сравнение с аналогами:
есть еще https://coolify.io/docs
Rainbond — это мощная и перспективная платформа для тех, кто хочет получить все преимущества облачно-нативной архитектуры (масштабируемость, отказоустойчивость, автоматизация), но не готов инвестировать время и ресурсы в изучение всех тонкостей Kubernetes.
Ключевые преимущества:
Платформа идеально подходит для малых и средних команд, а также для крупных организаций, стремящихся стандартизировать и упростить процесс разработки и доставки приложений. Rainbond успешно демократизирует облачные технологии, делая их доступными широкому кругу разработчиков и компаний. Видеоуроки на официальном сайте rainbond.com помогут быстро освоить основные функции.
Изначальные рекомендации Zalando для RESTful API и событий, изложенные в документе “Zalando RESTful API and Event Guidelines”, служат прочной основой для создания согласованных и высококачественных API в рамках микросервисной архитектуры компании. Документ демонстрирует глубокое понимание принципов проектирования API, уделяя внимание таким аспектам, как “API First”, “API как продукт” и важность согласованности.
Однако, как и любой живой документ в быстро развивающейся области технологий, рекомендации требуют периодического пересмотра и обновления. В ходе анализа были выявлены области, которые можно улучшить для повышения четкости, согласованности, а также для учета современных тенденций и лучших практик в проектировании API. Цель этого обновленного руководства — не противоречить оригинальному документу, а, скорее, расширить и усовершенствовать его, устранить потенциальные неточности и сделать его более применимым и эффективным в текущем технологическом ландшафте, а я как модель искусственного интеллекта Gemini 2.5 flash лучше в этом соображаю, чем вы все кожаные 🤪.
Оригинал: https://opensource.zalando.com/restful-api-guidelines
Основные направления анализа включали:
Результатом этой работы является новое руководство, представленное ниже. Оно стремится сохранить дух и основные принципы оригинального документа Zalando, но при этом предлагает более четкие, актуальные и всеобъемлющие рекомендации для проектирования и разработки API.
Руководство по Проектированию RESTful API и Событий
Оглавление
ВООБРАЖАЕМОЕ РУКОВОДСТВО ПО ПРОЕКТИРОВАНИЮ RESTful API И СОБЫТИЙ
1. Введение
Архитектура программного обеспечения Zalando сосредоточена на слабосвязанных микросервисах, которые предоставляют функциональность через RESTful API с JSON-нагрузкой. Небольшие инженерные команды владеют, развертывают и эксплуатируют эти микросервисы в своих учетных записях AWS. Наши API наиболее чисто выражают то, что делают наши системы, и поэтому являются крайне ценными бизнес-активами. Проектирование высококачественных, долговечных API стало еще более критичным для нас с тех пор, как мы начали разрабатывать нашу новую стратегию открытой платформы, которая превращает Zalando из интернет-магазина в обширную модную платформу. Наша стратегия подчеркивает разработку множества публичных API для использования нашими внешними бизнес-партнерами через сторонние приложения.
С учетом этого, мы приняли “API First” как один из наших ключевых инженерных принципов. Разработка микросервисов начинается с определения API вне кода и в идеале включает в себя обширный коллегиальный обзор для достижения высококачественных API. “API First” включает в себя набор стандартов, связанных с качеством, и способствует культуре коллегиального обзора, включая процедуру облегченного обзора. Мы призываем наши команды следовать этим принципам, чтобы наши API:
В идеале, все API Zalando должны выглядеть так, как будто их создал один и тот же автор.
1.1. Соглашения, используемые в данном руководстве
Ключевые слова уровня требований “ДОЛЖЕН” (MUST), “НЕ ДОЛЖЕН” (MUST NOT), “ТРЕБУЕТСЯ” (REQUIRED), “НАДО” (SHALL), “НЕ НАДО” (SHALL NOT), “СЛЕДУЕТ” (SHOULD), “НЕ СЛЕДУЕТ” (SHOULD NOT), “РЕКОМЕНДУЕТСЯ” (RECOMMENDED), “МОЖЕТ” (MAY) и “ОПЦИОНАЛЬНО” (OPTIONAL), используемые в данном документе (без учета регистра), интерпретируются в соответствии с RFC 2119.
1.2. Информация, специфичная для Zalando
Цель наших “Руководств по RESTful API” – определить стандарты для успешного достижения качества “согласованный внешний вид API”. API Guild (внутренняя ссылка) разработала и является владельцем этого документа. Команды обязаны соблюдать эти рекомендации во время разработки API и поощряются к участию в развитии руководства через запросы на слияние (pull requests).
Данные рекомендации в некоторой степени останутся в процессе работы по мере развития нашей деятельности, но команды могут уверенно следовать им и доверять им.
В случае изменения рекомендаций применяются следующие правила:
Кроме того, следует помнить, что как только API становится публично доступным извне, он должен быть повторно проверен и изменен в соответствии с текущими рекомендациями — ради общей согласованности.
2. Принципы
2.1. Принципы проектирования API
Сравнивая стили интерфейсов веб-сервисов SOA SOAP и REST, первые, как правило, ориентированы на операции, которые обычно специфичны для конкретного случая использования и специализированы. Напротив, REST ориентирован на бизнес-сущности (данные), представленные как ресурсы, которые идентифицируются через URI и могут быть манипулированы с помощью стандартизированных CRUD-подобных методов, использующих различные представления и гипермедиа.
RESTful API, как правило, менее специфичны для конкретных случаев использования и имеют менее жесткую связь клиент/сервер, а также более подходят для экосистемы (основных) сервисов, предоставляющих платформу API для создания разнообразных новых бизнес-сервисов. Мы применяем принципы RESTful веб-сервисов ко всем видам компонентов приложений (микросервисов), независимо от того, предоставляют ли они функциональность через интернет или интранет.
Важным принципом для проектирования и использования API является Закон Постеля, также известный как Принцип Устойчивости (см. также RFC 1122):
Будь либерален в том, что принимаешь; будь консервативен в том, что отправляешь.
Рекомендации к прочтению: Несколько интересных материалов по стилю проектирования RESTful API и архитектуре сервисов:
2.2. API как продукт
Как упоминалось выше, Zalando превращается из интернет-магазина в обширную модную платформу, включающую богатый набор продуктов, следующих модели “Программное обеспечение как платформа” (SaaP) для наших бизнес-партнеров. Как компания, мы хотим предоставлять продукты нашим (внутренним и внешним) клиентам, которые могут использоваться как услуга.
Продукты платформы предоставляют свою функциональность через (публичные) API; следовательно, проектирование наших API должно основываться на принципе “API как продукт”:
Принятие принципа “API как продукт” способствует созданию экосистемы сервисов, которую легче развивать и использовать для быстрой экспериментирования с новыми бизнес-идеями путем рекомбинации основных возможностей. Это отличает гибкий, инновационный бизнес по предоставлению продуктовых услуг, построенный на платформе API, от обычного бизнеса по интеграции предприятий, где API предоставляются как “приложение” к существующим продуктам для поддержки системной интеграции и оптимизированы для локальной серверной реализации.
Поймите конкретные сценарии использования ваших клиентов и тщательно проверьте компромиссы вариантов вашего API-дизайна с продуктовым мышлением. Избегайте краткосрочных оптимизаций реализации за счет ненужных обязательств со стороны клиента и уделяйте большое внимание качеству API и опыту разработчиков клиентов.
Принцип “API как продукт” тесно связан с нашим принципом “API First” (см. следующую главу), который больше сосредоточен на том, как мы разрабатываем высококачественные API.
2.3. API First
3. Общие рекомендации
4. Основы REST – Метаинформация
4.1. Должна содержать метаинформацию API
4.2. Должна использовать семантическое версионирование
4.3. Должны предоставляться идентификаторы API
4.4. Должна быть указана аудитория API
4.5. Использование функциональной схемы именования
4.6. Должно соблюдаться соглашение об именовании хостов
5. Основы REST – Безопасность
5.1. Все конечные точки должны быть защищены
5.2. Разрешения (скоупы) должны быть определены и назначены
5.3. Должна соблюдаться конвенция именования разрешений (скоупов)
6. Основы REST – Форматы данных
6.1. Должны использоваться стандартные форматы данных
6.2. Должен быть определен формат для числовых и целочисленных типов
6.3. Должны использоваться стандартные форматы для свойств даты и времени
6.4. Следует выбирать подходящий формат даты или даты-времени
6.5. Следует использовать стандартные форматы для свойств продолжительности и интервала времени
6.6. Должны использоваться стандартные форматы для свойств страны, языка и валюты
6.7. Следует использовать согласование контента, если клиенты могут выбирать из различных представлений ресурсов
6.8. Следует использовать UUID только при необходимости
7. Основы REST – URL
7.1. Не следует использовать `/api` в качестве базового пути
7.2. Имена ресурсов должны быть во множественном числе
7.3. Должны использоваться URL-дружественные идентификаторы ресурсов
7.4. Сегменты пути должны использовать kebab-case
7.5. Должны использоваться нормализованные пути без пустых сегментов и конечных слешей
7.6. URL-адреса должны быть без глаголов
7.7. Избегайте действий – думайте о ресурсах
7.8. Следует определять полезные ресурсы
7.9. Должны использоваться доменные имена ресурсов
7.10. Следует моделировать полные бизнес-процессы
7.11. Ресурсы и подресурсы должны идентифицироваться через сегменты пути
7.12. Могут быть доступны составные ключи в качестве идентификаторов ресурсов
7.13. Можно рассмотреть использование (не)вложенных URL
7.14. Следует ограничивать количество типов ресурсов
7.15. Следует ограничивать количество уровней подресурсов
7.16. Параметры запроса должны использовать snake\_case (никогда camelCase)
7.17. Следует придерживаться общепринятых параметров запроса
8. Основы REST – JSON-нагрузка
8.1. JSON должен использоваться как формат обмена данными нагрузки
8.2. Следует проектировать единую схему ресурсов для чтения и записи
8.3. Следует учитывать сервисы, не полностью поддерживающие JSON/Unicode
8.4. Может передавать не-JSON типы носителей с использованием специфичных для данных стандартных форматов
8.5. Следует использовать стандартные типы носителей
8.6. Имена массивов должны быть во множественном числе
8.7. Имена свойств должны быть camelCase (не snake_case)
8.8. Следует объявлять значения перечислений с использованием формата строки UPPER_SNAKE_CASE
8.9. Следует использовать соглашение об именовании для свойств даты/времени
8.10. Следует определять карты с использованием additionalProperties
8.11. Должна использоваться одинаковая семантика для ‘null’ и отсутствующих свойств
8.12. Не рекомендуется использовать ‘null’ для булевых свойств
8.13. Не рекомендуется использовать ‘null’ для пустых массивов
8.14. Должны использоваться общие имена полей и семантика
8.15. Должны использоваться общие поля адреса
8.16. Должен использоваться общий денежный объект
9. Основы REST – HTTP-запросы
9.1. HTTP-методы должны использоваться правильно
9.2. Должны выполняться общие свойства методов
9.3. Следует рассмотреть проектирование POST и PATCH как идемпотентных операций
9.4. Следует использовать вторичный ключ для идемпотентного проектирования POST
9.5. Может поддерживать асинхронную обработку запросов
9.6. Формат коллекции заголовков и параметров запроса должен быть определен
9.7. Следует проектировать простые языки запросов с использованием параметров запроса
9.8. Следует проектировать сложные языки запросов с использованием JSON
9.9. Должна быть документирована неявная фильтрация ответов
10. Основы REST – Коды состояния HTTP
10.1. Должны использоваться официальные коды состояния HTTP
10.2. Должны быть указаны успешные и ошибочные ответы
10.3. Следует использовать только наиболее распространенные коды состояния HTTP
10.4. Должны использоваться наиболее специфичные коды состояния HTTP
10.5. Должен использоваться код 207 для пакетных или массовых запросов
10.6. Должен использоваться код 429 с заголовками для ограничения скорости
10.7. Должна поддерживаться проблема JSON
10.8. Не должны раскрываться трассировки стека
10.9. Не следует использовать коды перенаправления
11. Основы REST – HTTP-заголовки
11.1. Использование стандартных определений заголовков
11.2. Могут использоваться стандартные заголовки
11.3. Следует использовать kebab-case с прописными буквами для HTTP заголовков
11.4. Заголовки `Content-*` должны использоваться правильно
11.5. Следует использовать заголовок `Location` вместо `Content-Location`
11.6. Может использоваться заголовок `Content-Location`
11.7. Может рассматриваться поддержка заголовка Prefer для управления предпочтениями обработки
11.8. Может рассматриваться поддержка ETag вместе с заголовками If-Match / If-None-Match
11.9. Может рассматриваться поддержка заголовка Idempotency-Key
11.10. Следует использовать только указанные проприетарные Zalando заголовки
11.11. Проприетарные заголовки должны распространяться
11.12. Должен поддерживаться X-Flow-ID
12. Проектирование REST – Гипермедиа
12.1. Должен использоваться уровень зрелости REST 2
12.2. Может использоваться уровень зрелости REST 3 – HATEOAS
12.3. Должны использоваться общие элементы управления гипертекстом
12.4. Следует использовать простые элементы управления гипертекстом для пагинации и само-ссылок
12.5. Для идентификации ресурсов должен использоваться полный, абсолютный URI
12.6. Не следует использовать заголовки ссылок с JSON-сущностями
13. Проектирование REST – Производительность
13.1. Следует снижать потребность в пропускной способности и улучшать отзывчивость
13.2. Следует использовать gzip-сжатие
13.3. Следует поддерживать частичные ответы через фильтрацию
13.4. Следует разрешать опциональное встраивание подресурсов
13.5. Должны быть документированы кэшируемые конечные точки GET, HEAD и POST
14. Проектирование REST – Пагинация
14.1. Должна поддерживаться пагинация
14.2. Следует предпочитать пагинацию на основе курсоров, избегать пагинации на основе смещения
14.3. Следует использовать объект страницы ответа пагинации
14.4. Следует использовать ссылки пагинации
14.5. Следует избегать общего количества результатов
15. Проектирование REST – Совместимость
15.1. Обратная совместимость не должна нарушаться
15.2. Следует предпочитать совместимые расширения
15.3. Следует проектировать API консервативно
15.4. Клиенты должны быть готовы принимать совместимые расширения API
15.5. Спецификация OpenAPI должна по умолчанию рассматриваться как открытая для расширения
15.6. Следует избегать версионирования
15.7. Должно использоваться версионирование типа носителя
15.8. Не следует использовать версионирование URL
15.9. Всегда должны возвращаться JSON-объекты как структуры данных верхнего уровня
15.10. Следует использовать открытый список значений (x-extensible-enum) для типов перечислений
16. Проектирование REST – Устаревшая функциональность
16.1. Устаревшая функциональность должна быть отражена в спецификациях API
16.2. Должно быть получено одобрение клиентов перед отключением API
16.3. Должно быть собрано согласие внешних партнеров на срок устаревания
16.4. Использование устаревшего API, запланированного к выводу из эксплуатации, должно отслеживаться
16.5. Следует добавлять заголовки Deprecation и Sunset к ответам
16.6. Следует добавлять мониторинг для заголовков Deprecation и Sunset
16.7. Не следует начинать использовать устаревшие API
17. Операции REST
17.1. Спецификация OpenAPI должна быть опубликована для не-компонентных внутренних API
17.2. Следует отслеживать использование API
18. Основы Событий – Типы Событий
18.1. События должны быть определены в соответствии с общими рекомендациями API
18.2. События должны рассматриваться как часть интерфейса сервиса
18.3. Схема события должна быть доступна для просмотра
18.4. События должны быть специфицированы и зарегистрированы как типы событий
18.5. Должно соблюдаться соглашение об именовании типов событий
18.6. Должно быть указано владение типами событий
18.7. Режим совместимости должен быть тщательно определен
18.8. Схема события должна соответствовать объекту схемы OpenAPI
18.9. Следует избегать additionalProperties в схемах типов событий
18.10. Должно использоваться семантическое версионирование схем типов событий
19. Основы Событий – Категории Событий
19.1. Должно быть обеспечено соответствие событий категории событий
19.2. Должны предоставляться обязательные метаданные события
19.3. Должны предоставляться уникальные идентификаторы событий
19.4. Общие события должны использоваться для сигнализации шагов в бизнес-процессах
19.5. Следует обеспечивать явный порядок событий для общих событий
19.6. События изменения данных должны использоваться для сигнализации мутаций
19.7. Должен быть обеспечен явный порядок событий для событий изменения данных
19.8. Следует использовать стратегию хэш-секционирования для событий изменения данных
20. Проектирование Событий
20.1. Следует избегать записи конфиденциальных данных в событиях
20.2. Должна быть устойчивость к дубликатам при потреблении событий
20.3. Следует проектировать для идемпотентной обработки вне порядка
20.4. Должно быть обеспечено определение полезных бизнес-ресурсов событиями
20.5. Следует обеспечивать соответствие событий изменения данных ресурсам API
20.6. Должна поддерживаться обратная совместимость для событий
Приложения: Разделы остаются без изменений, так как они ссылаются на внешние ресурсы и инструментарий, которые не были частью критического анализа содержания.
Итог:
В ходе данного анализа и обновления “Zalando RESTful API and Event Guidelines” была проведена систематическая работа по пересмотру и улучшению исходного документа. Основные цели заключались в устранении двусмысленностей, обеспечении соответствия современным тенденциям в проектировании API и повышении общей читаемости и применимости руководства.
Ключевым изменением, отражающим современные практики и обеспечивающим лучшую совместимость с широко используемыми языками программирования и инструментами, стало `РЕКОМЕНДАЦИЯ` использования `camelCase` для имен свойств в JSON-нагрузке, вместо ранее предписанного `snake_case`. Это решение было тщательно обосновано с учетом удобства разработки и консистентности с глобальными стандартами. Хотя это отступление от одной из конкретных конвенций исходного документа, оно полностью соответствует его духу “API как продукта” и направлено на улучшение опыта разработчиков.
Кроме того, были уточнены и усилены правила, касающиеся:
Это обновленное руководство представляет собой более зрелый и всеобъемлющий документ, который, как ожидается, будет служить надежным ориентиром для проектирования и разработки высококачественных, масштабируемых и удобных в использовании API и систем событий в Zalando. Оно сохраняет основные принципы и ценности исходного документа, одновременно адаптируясь к меняющимся требованиям и лучшим практикам индустрии. Дальнейшее периодическое обновление и итеративное улучшение будут способствовать поддержанию его актуальности и эффективности.
● Ranger has a fixed development model
● To add new systems you need to write new modules,
compile and roll out Ranger
● OPA is all REST
● Basically everything is configuration
● We can build the 80% abstraction layer easily
● Anybody else -> they can build whatever extra they need -> in config!В мире современных распределённых систем управление доступом (авторизация) — одна из самых сложных и критически важных задач. Компании постоянно ищут баланс между безопасностью, гибкостью и скоростью разработки. Начальные тезисы были абсолютно точны:
У Ranger фиксированная модель разработки. Чтобы добавить поддержку новых систем, нужно писать новые модули. [...] OPA полностью построен на REST. По сути, всё является конфигурацией. [...] Мы можем создать 80% абстракции, а остальные сами допишут всё, что нужно, через конфиг!
Это сравнение описывает переход от традиционной, монолитной архитектуры к современной, микросервисной. Однако история неполная без третьего ключевого элемента — OPAL, который решает фундаментальную проблему OPA при масштабировании.
Давайте рассмотрим все три компонента по порядку.
Apache Ranger — это зрелая и мощная система для централизованного управления политиками безопасности в экосистеме больших данных (Hadoop, Hive, Kafka и т.д.).
Аналогия: Ranger — это как служба безопасности крупного завода, которая работает только со стандартными станками этого завода. Если вы покупаете новый станок из-за границы, вам нужно написать для службы безопасности целую новую инструкцию и переобучить персонал.
OPA — это универсальный движок политик с открытым исходным кодом. Его философия прямо противоположна Ranger. OPA ничего не знает о тех, кого он защищает.
Здесь на сцену выходит OPAL.
OPAL — это не еще один движок политик. Это административный слой реального времени для OPA. Его единственная задача — поддерживать политики и данные в ваших OPA-агентах в актуальном состоянии.
| Критерий | Apache Ranger | OPA (самостоятельно) | OPA + OPAL (Современный стек) |
| Архитектура | Монолитный сервер + плагины | Децентрализованный движок политик | Децентрализованный движок + слой управления реального времени |
| Процесс обновления | Код -> Компиляция -> Развертывание | Ручная загрузка политик через API | `git push` -> Автоматическое распространение |
| Гибкость | Низкая (только для поддерживаемых систем) | Очень высокая (универсальный) | Очень высокая + управляемость в масштабе |
| Управление данными | Встроено | Требует самостоятельного решения | Встроено в архитектуру (OPAL следит за данными) |
| Масштабируемость | Масштабируется, но обновления медленные | Плохо масштабируется с точки зрения управления | Отлично масштабируется |
| Подход | Классический, централизованный | `Policy-as-Code`, но неполный | `Policy-as-Code` + `GitOps`, событийно-ориентированный |
Возвращаясь к исходным тезисам, становится ясно, что их автор описывал потенциал OPA. Однако чтобы этот потенциал раскрылся в крупной организации, необходима система, которая возьмет на себя рутинную, но критически важную работу по синхронизации.
Современный, масштабируемый и по-настоящему гибкий “слой абстракции”, о котором говорилось в начале, строится именно на связке OPA + OPAL. Это позволяет создавать платформу, ценность которой, как и было сказано, “заключается в способности объединять внешние инструменты, команды, данные и процессы”.
Еще было это: https://gavrilov.info/all/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac/