Apache Iceberg: Индиана Джонс и Каталог судьбы
В феврале этого года проект с красивым именем Polaris тихо стал полноценным проектом фонда Apache. Новость прошла мимо почти всех - ну стал и стал, мало ли их там. А между тем это одна из тех новостей, которые лет через пять будут называть поворотной точкой. Потому что Polaris - это каталог. А каталог в мире Iceberg - то самое место, где на самом деле лежит власть над вашими данными.
Звучит громко, понимаю. Сейчас объясню с самого начала, без спешки, потому что тема того стоит. Начнём даже не с каталогов, а на шаг раньше - с того, что такое вообще этот Iceberg, вокруг которого последний год прыгают все вендоры разом.
Коротко
- Apache Iceberg - это не база и не движок, а открытый способ описать «таблицу» поверх обычных файлов (Parquet) в объектном хранилище. То есть дать конечному пользователю возможность работать с россыпью файлов как с единой таблицей данных и выполнять к этой таблице SQL-запросы. Он добавляет к россыпи файлов слой метаданных: какие файлы прямо сейчас входят в таблицу, какая схема, какие были версии.
- Это даёт то, чего у голых файлов не было: транзакции, откат к прошлым версиям, эволюцию схемы, и главное - одну таблицу читают и пишут сразу несколько движков (Spark, Trino, ClickHouse, DuckDB).
- Но у Iceberg есть уязвимое место: метаданные - тоже файлы, и кто-то должен атомарно держать указатель на «сейчас актуальную версию». Этим занимается каталог.
- Без каталога, на голом S3, два одновременных писателя молча затирают друг друга - теряется коммит, без единой ошибки в логах.
- Формат данных все вендоры открыли и согласовали. Поэтому борьба переехала на каталог: кто держит каталог, тот держит права доступа и решает, какие движки вообще увидят ваши данные.
- Polaris (изначально от Snowflake, теперь проект Apache) - один из главных претендентов на роль этого каталога. Метаданные он, кстати, держит в обычной реляционной базе, на практике - в PostgreSQL.
Сначала - зачем вообще появился Iceberg
Представьте, что у вас озеро данных. На практике это означает вот что: где-то в объектном хранилище (S3, или в вашем ЦОДе что-то S3-совместимое) лежат тысячи файлов в формате Parquet. Parquet - хороший колоночный формат, компактный, быстрый на чтении. Проблема в другом.
Куча файлов - это ещё не таблица.
Смотрите, что вы не можете сделать с голой папкой Parquet-файлов. Не можете нормально удалить или обновить строку - файлы неизменяемы, надо переписывать целиком. Не можете спросить «а как эта таблица выглядела в прошлый вторник» - никакой истории нет. Не можете безопасно писать в неё с двух заданий разом - они устроят гонку и попортят друг другу данные. Не можете поменять схему (добавить колонку) без плясок с бубном. И если один инструмент решил, что «таблица» - это файлы с 1 по 100, а другой в это время дописал 101-й, они друг про друга не знают.
Долгое время эту роль пытался играть Hive - старая добрая инфраструктура из мира Hadoop. Он вёл список: вот такая-то таблица состоит из вот таких-то папок. Работало, но с оговорками, которые к нынешним объёмам и требованиям превратились в постоянную головную боль.
И вот тут появляется Iceberg. Придумали его в Netflix, отдали в Apache, и за несколько лет он стал стандартом де-факто. Идея простая до элегантности.
Что такое Iceberg на самом деле
Iceberg - это не хранилище (данные по-прежнему лежат в вашем S3) и не движок (он ничего не считает). Это спецификация. Договорённость о том, как поверх обычных файлов описать полноценную таблицу.
Работает это так. Рядом с файлами данных Iceberg держит слой метаданных - несколько служебных файлов, которые описывают, что вообще происходит с таблицей. Если совсем упрощать, там записано три вещи: какие именно файлы данных прямо сейчас составляют таблицу, какая у таблицы схема (колонки и их типы), и какие у неё были предыдущие состояния.
Вот это «предыдущие состояния» - ключевой трюк. Каждый раз, когда вы что-то пишете в Iceberg-таблицу, он не портит старое, а создаёт новую версию описания - новый снимок, снапшот. Старые снимки остаются лежать. Отсюда и растут почти все приятные свойства.
Что вы получаете взамен россыпи файлов:
Транзакции. Запись либо целиком применилась, либо целиком нет - как в нормальной базе. Никаких «полтаблицы обновилось, а на середине упало».
Путешествие во времени. Можно спросить таблицу «покажи, как ты выглядела на прошлой неделе» - и она покажет, потому что тот снимок никуда не делся. Для аналитики, аудита и разбора инцидентов это бесценно: отчёт разошёлся с ожиданиями - откатились на снимок трёхдневной давности и сравнили.
Эволюция схемы. Добавить колонку, переименовать, поменять тип - без переписывания всех данных. Iceberg отслеживает колонки по внутренним идентификаторам, а не по именам и позициям, поэтому старые файлы продолжают читаться корректно.
И самое, на мой взгляд, важное - ради чего всё и затевалось. Данные больше не заперты внутри одной системы. Раньше, чтобы работать с таблицей, вы заводили её в конкретную платформу, и данные становились её заложником: чужой формат, чужой движок, вендор диктует и правила, и цену. Iceberg это разрывает. Таблица лежит в открытом формате на дешёвом объектном хранилище, сама по себе, отдельно от того, кто её считает.
Отсюда, кстати, растёт и та самая мультидвижковость: раз данные ничьи, к ним можно подпустить хоть Spark, хоть Trino, хоть ClickHouse, хоть DuckDB на ноутбуке аналитика - все увидят одну и ту же таблицу. Но подчеркну важное, потому что об этом часто забывают: ценно это даже если движок у вас всего один. Суть не в том, чтобы натравить на данные пять инструментов. Суть в том, что хранилище перестало быть частью вендорской платформы и масштабируется само по себе - дёшево, горизонтально и независимо от того, чем вы эти данные обрабатываете.
Чтобы это не висело в воздухе, вот живой пример из практики. Представьте поток данных в Kafka - скажем, изменения из боевой базы, которые туда льёт Debezium. Дальше их надо сложить в озеро, и делается это Kafka-коннектором. Возьмёте обычный S3-коннектор - он разложит данные по бакету простыми .parquet-файлами, и на руках у вас окажется ровно та самая россыпь: файлы есть, а таблицы нет.
Теперь поменяйте его на Iceberg-коннектор. Поток тот же самый, но на выходе получается уже полноценная таблица. Под капотом всё те же parquet ложатся в то же хранилище, только каждый файл сразу прикрепляется к метаданным Iceberg и попадает в таблицу атомарным коммитом. Снаружи это ведёт себя как обычная таблица: идёшь к ней с SQL из любого движка, есть история версий, всё как положено. Вот она, разница между «положить файл» и «записать в таблицу», во всей красе.
Есть, правда, и оборотная сторона: при такой потоковой записи мелких файлов быстро набегает много, и таблицу приходится периодически прибирать - склеивать их и подчищать старые снимки. Работы немного, но она нужна. Впрочем, это уже тема для отдельного поста.
Красивая картинка. Но именно здесь, за красивой картинкой, и прячется тот самый вопрос, ради которого всё затевалось.
Вещь, которую надо подсветить ярче
Смотрите внимательно. Метаданные Iceberg - это ведь тоже файлы. Тот самый верхний файл-описание, где записано «актуальная версия таблицы вот такая», физически лежит в том же объектном хранилище.
И теперь вопрос на засыпку. Приходят два процесса писать в таблицу одновременно. Каждый берёт текущую версию, добавляет свои данные, готовит новую версию описания. И оба хотят сказать: «Всё, теперь актуальная версия - моя». Кто-то же должен рассудить, чья версия станет новой официальной. Причём рассудить мгновенно и без вариантов «оба выиграли».
Вот эту работу - держать указатель на единственно верную, текущую версию таблицы и атомарно его переключать - и выполняет каталог.
Это и есть его назначение, если убрать всю мишуру. Каталог хранит буквально одну вещь: указатель на текущий файл метаданных таблицы. Всё остальное - схема, история, списки файлов - лежит в самих метаданных в хранилище. Каталог держит только стрелочку «вот сейчас правильная версия - эта».
Запомните это, потому что вокруг каталогов много маркетингового тумана, а суть - вот такая скромная. Одна стрелочка. Но кто держит эту стрелочку, тот и контролирует таблицу.
Как каталог переключает стрелку (и почему без него нельзя)
Механика коммита в Iceberg похожа на смену таблички у входа в кабинет. Писатель готовит новую табличку (новый файл метаданных) заранее, в сторонке. А потом делает одно короткое движение - меняет старую табличку на новую. И вот это движение должно быть атомарным: либо табличку сменили, либо нет, промежуточного состояния «висят две» быть не должно.
На языке баз это называется compare-and-swap: «поменяй указатель на новый, но только если он всё ещё равен тому, от которого я отталкивался». Если за то время, пока я готовил свою версию, кто-то другой уже сменил табличку - моя замена не проходит, я получаю от каталога отлуп и должен начать заново, уже от свежей версии.
Разные каталоги делают это движение по-разному, но суть одна. Если каталог живёт в обычной SQL-базе, то весь атомарный коммит - это буквально один UPDATE с условием «поменяй указатель, где он равен ожидаемому». База гарантирует, что из двух гонщиков ровно один обновит строку, а второй увидит ноль изменённых строк и поймёт, что проиграл гонку. Дёшево и надёжно, потому что за атомарность отвечает СУБД, которая это умеет с рождения.
А теперь - что будет, если каталога нет вовсе.
Есть соблазн обойтись без него. Iceberg умеет работать в режиме, когда роль «того, кто держит стрелку» играет сама файловая система: положил новый файл версии, переименовал - вот и весь коммит. На HDFS это работает, потому что там переименование файла атомарно и с проверкой «а нет ли уже такого». То есть файловая система сама играет роль арбитра.
Но почти никто сегодня не держит озеро на HDFS. Все на S3 или S3-совместимом хранилище. А у S3 нет атомарного переименования - под капотом это копирование плюс удаление, и никакой проверки «файл уже существует». И вот тут случается тихая потеря данных.
Два процесса собрали каждый свою версию «сорок третью». Оба «переименовывают» свой файл в финальное имя. Оба успешно. Второй молча затирает первого. Коммит первого исчезает - вместе с данными, которые он записал. И самое неприятное: нигде не появляется ошибки. В логах чисто. Просто в какой-то момент обнаруживается, что часть данных, которые точно записались, куда-то делись. Разбирать такое - отдельное удовольствие, я вам доложу.
Именно поэтому в проде без каталога делать нечего. Показательный факт: Trino, один из самых популярных движков для работы с Iceberg, с данными на S3 работает прекрасно - но только через нормальный каталог. Бескаталожного режима, где роль арбитра играет сама файловая система, он не поддерживает вовсе: в списке доступных типов каталога у Trino шесть вариантов (Hive Metastore, Glue, REST, JDBC, Nessie, Snowflake), и файлового среди них просто нет. Разработчики решили не давать людям возможность выстрелить себе в ногу.
Так что каталог - не украшение и не «ещё один сервис в стеке ради галочки». Это то, что превращает набор файлов в таблицу, с которой безопасно работать нескольким людям и системам одновременно. И заодно, раз уж он всё равно стоит на входе и решает, кто к таблице обращается, на него навешивают ещё две работы: права доступа (кому какие таблицы видны) и выдачу временных ключей к хранилищу (чтобы движку не раздавать постоянные пароли от вашего S3).
Если совсем заострить: без каталога Iceberg - это лежащий на диске формат, договорённость и ничего больше. С каталогом он оживает и начинает вести себя как настоящая таблица, к которой можно прийти с запросом. Каталог - единственная деталь во всей этой конструкции, которую вы реально держите запущенной как сервис. Всё остальное либо просто лежит в хранилище, либо приходит и уходит.
Какие бывают каталоги
Хорошая новость: почти все современные каталоги говорят на одном языке. Есть общий стандарт - Iceberg REST Catalog, по сути описание того, как движок должен разговаривать с каталогом по сети. И это не реализация, а именно протокол, контракт. Любой каталог, который его поддерживает, виден всем движкам одинаково, а движку без разницы, что там за каталог на другом конце провода. Ниже вернусь к тому, что этот общий язык на практике соблюдают с оговорками, но сама идея правильная.
Сразу уточню, а то здесь часто путаются. REST-каталог - это не программа, которую скачал и запустил. Это протокол: набор сетевых команд, которые каталог обязан понимать, если к нему стучатся по этому стандарту. А чтобы всё заработало, кто-то всё равно должен поднять и держать запущенным сервер, эти команды исполняющий. Вот этот сервер и есть каталог - Polaris, Lakekeeper и прочие из списка ниже. Короче: REST - это язык, а сервер-каталог - тот, кто на нём говорит. Никакого API без работающего сервиса не бывает - где-то он крутится всегда.
Зачем вообще понадобился общий язык. Раньше каждый движок умел разговаривать с каждым каталогом по-своему: отдельный код-клиент под Hive, отдельный под Glue, отдельный под базу. Пять движков и пять каталогов - это двадцать пять отдельных интеграций, и каждый новый каталог приходилось прикручивать ко всем движкам заново. REST разрубает узел: движок учит один язык и через него общается с любым сервером-каталогом, который тот же язык понимает. Один клиент вместо зоопарка.
Теперь как оно работает вживую. Движок хочет прочитать таблицу - шлёт серверу-каталогу сетевой запрос: дай текущую версию таблицы orders. Сервер лезет в свою базу, тот самый Postgres, находит указатель на актуальный файл метаданных и отвечает: лежит там-то; заодно нередко выдаёт временный ключ к хранилищу. Дальше движок идёт уже прямо в хранилище и читает файлы сам. Сервер данными не ворочает - он держит стрелку и указывает направление.
С записью тоньше, и вот тут главное. Движок готовит новую версию, а потом шлёт серверу не «поменяй», а «поменяй, только если текущая версия всё ещё вот эта». И сам атомарный обмен - ту самую смену таблички - делает уже сервер, внутри транзакции своей базы. То есть compare-and-swap, о котором шла речь выше, в REST переезжает с движка на сервер. Потому сервер и должен работать постоянно: он единственный арбитр, он держит связь с базой метаданных и он разрешает споры между писателями. Движки приходят и уходят, а он стоит на входе всегда. Плюс приятный побочный эффект: движку больше не нужны ни прямой доступ к базе метаданных, ни постоянные пароли от хранилища - и то и другое остаётся за сервером, а движку выдаётся временный ключ ровно на одну операцию.
Теперь коротко про игроков, без которых картина неполная.
Hive Metastore - дедушка всех каталогов, наследие эпохи Hadoop. Работает, огромная установленная база, но капризный: то залипнет внутренняя блокировка, то при обрыве связи в неудачный момент таблица окажется указывающей на несуществующий файл (это реальный, задокументированный класс аварий, не страшилка). От него потихоньку уходят, но легаси живёт долго.
Каталог в обычной SQL-базе - самый простой и прямой вариант. Указатели на таблицы лежат строчками в PostgreSQL или другой реляционной базе, атомарность бесплатно достаётся от неё же. Ничего лишнего.
AWS Glue - каталог от Amazon. Если вы целиком живёте в AWS, это дефолт по инерции. Взамен - привязка к экосистеме и набор ограничений (например, потолок на число версий таблицы, за который на активной таблице реально можно упереться).
Project Nessie - каталог с изюминкой: он приносит в данные логику Git. Ветки, теги, коммиты, возможность собрать консистентный снимок сразу нескольких таблиц. Штука мощная для тех, кому нужны эксперименты над данными «в ветке» перед вливанием в основную. Правда, будущее у него теперь такое: его создатели (компания Dremio) объявили, что вливают Nessie в Polaris. То есть как самостоятельный проект он, похоже, доживает.
Unity Catalog - каталог от Databricks. Формально открыли исходники, но по факту вся сила - в закрытой облачной версии, а открытая заметно беднее. Центр тяжести - вокруг самого Databricks.
Lakekeeper - молодой и любопытный. Написан на Rust, это один компактный бинарник без тяжёлой Java-машины под ним, метаданные держит в PostgreSQL. Для тех, кто ставит всё у себя на земле, он особенно интересен: официально поддерживает on-premise S3-совместимые хранилища - те самые MinIO и подобные, которые крутятся в собственном ЦОДе. Молодой, поэтому местами ещё сыроват, но направление правильное.
И наконец Polaris, ради которого и затевался разговор. Про него - отдельно, чуть ниже.
Что во всём этом списке важно практику? Три вопроса, которые я задаю каждому каталогу. Можно ли поставить его у себя, а не только арендовать как облачный сервис. Кто им на самом деле управляет - сообщество или один вендор, который завтра поменяет правила. И переносимы ли настройки прав доступа, если вы решите съехать на другой каталог. Забегая вперёд: с последним всё грустно у всех.
Куда переехал замок от ваших данных
Вот теперь можно собрать картину целиком, и она любопытная.
Формат данных - Iceberg, Parquet под ним - открыт. Все крупные вендоры на это согласились, потому что закрытый формат сегодня стал бы поводом для клиента развернуться и уйти. Данные в открытом формате лежат в вашем хранилище и читаются кем угодно. На уровне файлов привязки к вендору больше нет, и это реальное достижение.
Но привязка не исчезла. Она переехала.
Она переехала ровно на тот слой, о котором вся статья, - на каталог. Смотрите: данные ваши и открытые, а вот стрелку на актуальную версию держит каталог. Права доступа - в каталоге. Выдачу ключей к хранилищу - в каталоге. И если каталог у вас арендованный, облачный, от конкретного вендора, то формально открытые данные всё равно живут по его правилам. Он решает, какие движки к ним пустить.
И есть деталь, которая добивает романтику окончательно. Права доступа между каталогами не переносятся вообще. Настроили вы тонкую политику - кто какие строки таблицы видит - в одном каталоге. Решили переехать на другой. Так вот, эта политика с вами не поедет, её придётся строить заново руками, потому что общего стандарта на перенос прав в индустрии просто нет. Данные - переносимы, а нажитая вокруг них система доступа - нет.
Плюс тот самый общий язык, REST-протокол, на практике соблюдают выборочно. Стандарт разрешает не реализовывать часть возможностей, и вендоры этим пользуются: у одного нет многоуровневых имён, у другого нельзя создать таблицу через протокол, у третьего не работает выдача ключей. Так что «просто подключитесь по стандарту» на деле нередко превращается в «подключитесь и упритесь в то, что половина нужного не поддержана».
Вывод, который я для себя сделал, простой. Выбор формата данных сегодня уже почти не имеет значения - берите Iceberg и не думайте. А вот выбор каталога - это и есть выбор того, кому вы доверяете держать стрелку и раздавать ключи. Это решение куда важнее, чем кажется, и его почему-то принимают в последнюю очередь и на автомате.
И, наконец, Polaris
Теперь понятно, почему я начал с новости про него.
Polaris - это каталог, который придумал Snowflake и в 2024 году отдал в открытый код, а в феврале 2026 он дорос до статуса полноценного проекта Apache. Почему это важно. Статус Apache означает, что проект больше не игрушка одного вендора, которую тот может закрыть или развернуть в свою сторону, - у него независимое управление под крылом фонда.
И тут есть тонкость, которая мне нравится. Вопреки ожиданиям, Polaris не остался «снежным» проектом под вывеской Apache. Председатель управляющего комитета - из компании Dremio, прямого соседа по рынку. В том же комитете сидят люди из Databricks - вообще-то конкурента. То есть за проектом стоят несколько вендоров сразу, и это делает его куда более нейтральной территорией, чем можно было ждать. Для стандарта, вокруг которого все должны договориться, это, пожалуй, лучший расклад.
А под капотом - деталь, от которой я, признаться, улыбнулся. Метаданные Polaris держит в обычной реляционной базе - на практике это PostgreSQL. Формально бэкенд умеет три варианта, но все они, если приглядеться, про один и тот же Postgres: сам PostgreSQL для боевой работы (вся документация написана под него), H2 для разработки и тестов (in-memory, в прод такое не ставят), и CockroachDB - но та подключается ровно как Postgres, потому что совместима с ним по протоколу. Куда ни ткни - под капотом язык Postgres. Тот самый указатель на актуальную версию таблицы, права, роли - всё живёт строчками в заурядной базе, которую любой инженер знает как облупленную. Никакой магии. Причём поставить Polaris можно и у себя: нужен Postgres, контейнер и объектное хранилище - привязки к облаку Snowflake для этого нет. А сам Snowflake свой облачный сервис-каталог построил ровно на том же самом Polaris, просто взял на себя эксплуатацию.
Вокруг этого и крутится свежий виток анонсов - тот же Snowflake недавно подал целую архитектуру под вывеской открытого лейкхауса, где Iceberg как формат, Polaris как каталог, и обещана двусторонняя работа с таблицами из чужих движков. Разбор этих обещаний с их мелким шрифтом - тема отдельная, тут важно другое: все дороги в этой истории ведут к каталогу. Формат уже поделили, воевать за него никто не хочет. Воюют за то, кто будет держать стрелку.
Что со всем этим делать на практике
Теперь полезное - как выбирать, без привязки к моде.
Если вы ставите всё у себя, на своей земле, и хотите Iceberg с нормальным каталогом - смотрите на Polaris (self-hosted, с Postgres под метаданными) или на Lakekeeper, если хочется лёгкости и вам близок его подход с S3-совместимым хранилищем в собственном ЦОДе. И тот и другой ставятся без облачного вендора за спиной.
Если вы целиком в AWS и не планируете съезжать - Glue по инерции проще всего, просто держите в голове его ограничения и потолки.
Если вам реально нужна логика веток над данными - эксперименты в ветке, консистентные снимки нескольких таблиц разом, - это по-прежнему Nessie, других таких нет. Но закладывайтесь на то, что проект вливается в Polaris, и планируйте с оглядкой.
И, наконец, не выбирайте по ложному критерию «а много ли у меня движков». Iceberg берут не ради зоопарка инструментов - его берут ради смены самой парадигмы хранения. Ради ухода от вендорозависимых платформ и от систем, которые для роли хранилища вообще не строились. Классические реляционные СУБД - MSSQL, Oracle, тот же PostgreSQL - хороши каждая в своём деле, но масштабируемым хранилищем на десятки и сотни терабайт они быть не задумывались; даже MPP-надстройки вроде Greenplum на этой роли сегодня выглядят хромой уткой.
Greenplum, к слову, - живая иллюстрация той самой вендорозависимости, от которой лейкхаус и уводит. Ещё недавно он был открытым и бесплатным, а в 2024 году, когда достался Broadcom вместе с VMware, открытую версию попросту свернули: репозитории заморозили, дальнейшее развитие ушло в платный Tanzu. Хочешь двигаться дальше - плати. Сообщество, правда, ответило по-своему: часть оригинальных разработчиков подхватила открытый код и увела его в форк под именем Cloudberry, который теперь развивается под крылом Apache. Но сам сюжет показателен - сегодня открыто и бесплатно, а завтра новый хозяин принял решение, и всё поменялось. И это даже не главный счёт. Стоимость владения таким кластером складывается из лицензий, специфического железа и дорогих рук, которые всё это держат на плаву. А отказоустойчивость и сопровождение MPP-кластера поверх Postgres - отдельная наука, где хватает своих граблей: балансировка сегментов, зеркала, восстановление после падения ноды. Открытый формат на дешёвом объектном хранилище снимает разом и вопрос вендора, и цену входа, и добрую часть эксплуатационной боли - и решает задачу даже тогда, когда движок обработки у вас один-единственный. Как это выглядит на практике, я разбирал отдельно - когда показывал устройство DWH на открытом стеке.
Пара слов про DuckLake
Раз уж речь зашла про Postgres под капотом, нельзя не упомянуть DuckLake - подход, который доводит эту мысль до логического конца. Идея почти дерзкая в своей простоте: а давайте вообще не будем разводить россыпь служебных файлов и отдельный каталог-сервис. Положим всё описание таблиц - и стрелки, и историю, и статистику по файлам - целиком в обычную SQL-базу. Данные так и лежат в Parquet в хранилище, а весь учёт - в паре десятков таблиц в PostgreSQL. Тогда коммит - это просто транзакция в базе, атомарность и одновременная запись достаются даром, как умеет любая нормальная СУБД лет уже тридцать.
Забавно, к чему пришли. Индустрия несколько лет строила сложный слой метаданных поверх файлов, изобретала протоколы каталогов и воевала за то, кто будет держать стрелку. А самый предсказуемый вариант - положить каталог в обычную реляционную базу, которая для управления согласованными данными и придумана. DuckLake это делает в лоб; у Polaris, если приглядеться, под капотом тот же Postgres, просто обёрнутый в сервис. Круг замкнулся.
И всё же я бы не спешил подавать DuckLake как «облегчённую замену Iceberg для тех, у кого данных немного». По трём причинам. Во-первых, данные имеют скверную привычку расти: то, что сегодня ворочает пара машин, через год превращается в то, ради чего и городят серьёзный лейкхаус, - и переезжать на бегу под нагрузкой не пожелаешь и врагу. Во-вторых, DuckLake живёт пока в своей первой версии - для фундамента, на котором стоит хранилище, это очень мало пройденного пути. И в-третьих, что для меня, человека, отвечающего за сохранность данных, важнее всего: за DuckLake стоит конкретный вендор, а у любого вендорского проекта есть ненулевой шанс однажды просто закрыться. Класть такое в основание хранилища - решение, которое принимают с открытыми глазами, а не потому что «нам так проще сейчас».
Так что DuckLake я держу на радаре как любопытное и верное по духу движение - оно про ту же простоту, к которой я и сам склоняюсь. Но не как готовую замену Iceberg. Присматриваться - да. Переносить на него боевое хранилище с расчётом «у нас всё равно немного данных» - рано и рискованно.
Когда всё это не нужно
И, для равновесия, - когда весь лейкхаус с Iceberg и каталогом не нужен вовсе. Ответ простой: когда данных у вас совсем немного или источников раз-два и обчёлся, и городить полноценное хранилище незачем. Если вся ваша аналитика помещается в пару таблиц обычной базы, а данные стекаются из одной-двух систем - оставайтесь на обычной СУБД и не морочьте себе голову. Iceberg, каталог, объектное хранилище начинают окупаться, когда данных и источников становится по-настоящему много, растёт разнообразие нагрузок и появляется смысл развязать хранение и обработку. До этого порога всё описанное - лишняя сложность на ровном месте. А вот когда обычная база уже трещит по швам - тогда вся эта конструкция и обретает смысл.
Что в итоге стоит унести с собой
Если из всего текста запомнить одно, пусть это будет вот что. В мире открытых форматов данных ваш формат почти ничего не решает - его давно поделили и открыли. Решает каталог. Это скромная на вид штука, которая держит единственную стрелку на актуальную версию таблицы, - но именно через неё проходят права доступа, выдача ключей и сам ответ на вопрос, какой движок увидит ваши данные, а какой нет.
Поэтому, когда в следующий раз будете строить или выбирать лейкхаус, потратьте на выбор каталога столько же внимания, сколько на всё остальное вместе взятое. Потому что данные - в открытом формате и вроде бы ваши. А вот стрелку держит кто-то. И очень важно, чтобы этот кто-то был или вы сами, или тот, кому вы осознанно доверяете, а не тот, кого выбрали в последний момент под красивую презентацию.
Основатель WARP.D. 30 лет в отрасли - от администрирования SQL Server до архитектуры data-платформ на открытом стеке. Банки, инвестиционные компании, федеральный ритейл.