Перейти к основному содержимому

Дневники баз данных, связанных с каталогом: об актуальности данных и записи

· 7 мин. чтения
Anna Lee
Software Engineer at dbt Labs
Mila Page
Senior Software Engineer at dbt Labs

Дневники баз данных, связанных с каталогом: об актуальности данных и записи​

В ноябре прошлого года на dbt Summit Джереми представил возможности dbt для работы с Iceberg на нескольких платформах.

Больше всего нас заинтересовала обещанная возможность взаимодействия между Databricks Unity Catalog и базами данных Snowflake, связанными с каталогом.

Все увлечены ИИ, но параллельно назревает ещё одна небольшая революция: команды выводят хранение данных за пределы платформ конкретных поставщиков. Уже несколько месяцев мы общаемся с пользователями, которые с энтузиазмом внедряют Iceberg как одну из основ своей архитектуры данных. Формат таблиц Iceberg и REST-каталоги Iceberg становятся стандартами, обеспечивающими такую гибкость.

В контексте dbt это проявляется в двух конкретных сценариях:

  • Масштабные проекты dbt: команды совместно используют одну логическую базу данных со множеством схем и сотнями или тысячами таблиц
  • Межплатформенная сетка данных: один проект в Snowflake, другой — в Databricks, с совместным использованием данных без необходимости вручную обновлять их или управлять указателями на метаданные

Что такое база данных, связанная с каталогом?​

В модели Iceberg каталог — это авторитетный источник метаданных таблиц: схем, снимков и истории изменений структуры. Он устроен так, чтобы несколько движков могли совместно работать с одним и тем же слоем метаданных. База данных, связанная с каталогом (catalog-linked database, CLD), — это механизм Snowflake, который представляет открытый каталог Apache Iceberg и все содержащиеся в нём таблицы Iceberg внутри Snowflake как обычную базу данных.

В идеале команды должны совместно использовать таблицы Iceberg на разных платформах без поочерёдного воссоздания указателей на их метаданные и без копирования самих данных. Представьте организацию, где финансовый отдел работает с показателями в Databricks, а команда маркетинга использует Snowflake. Команда Snowflake хочет получать актуальные данные из вышестоящей системы и даже время от времени вносить обратно ручные изменения строк. При традиционной синхронизации таблиц Databricks считался бы источником истины. С Iceberg и архитектурой на базе CLD обе платформы данных обращаются к одному источнику истины, определённому каталогом.

Предварительная настройка Snowflake позволяет без лишних усилий выполнять межплатформенные запросы к автоматически синхронизируемым объектам данных — по крайней мере, так обещано на бумаге. (Недавно Snowflake опубликовала пошаговое руководство по использованию CLD для двунаправленного обмена данными с Databricks — ещё несколько лет назад это казалось немыслимым, а сегодня уже возможно.)

Разрабатывая набор тестов, мы задумались, что происходит при масштабировании как чтения, так и записи. Добавим хаоса: что происходит, когда обе операции выполняются одновременно? Например, если бухгалтерия каждое утро в 6 часов записывает данные в кластер Databricks, а синхронизация с кластером Snowflake команды маркетинга занимает 2–3 часа, когда можно безопасно запускать их утренние задания анализа данных?

Наша методика тестирования​

Телеметрия реальных проектов dbt показывает, что крупные проекты насчитывают сотни моделей. В некоторых их тысячи. Для тестирования мы приняли наиболее рискованное допущение: каждая без исключения модель материализуется как таблица Iceberg. Это наша верхняя граница. (Для проектов dbt, внедряющих Iceberg, это редкость, но у команды могут быть веские причины для такого выбора.)

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

  1. Чтение в большом масштабе: Каковы накладные расходы, когда Snowflake читает таблицы, которыми управляет другая платформа?
  2. Запись в большом масштабе: Как меняется производительность при создании и обновлении множества таблиц и запросах больших объёмов метаданных?
  3. Актуальность при изменениях: Когда одна платформа обновляет данные, насколько надёжно и быстро другая видит эти изменения?

Для тех, кто хочет разобраться глубже, мы опубликовали полную методику тестирования и подробные результаты: https://github.com/dbt-labs/snow-dbx-iceberg-benchmark

Чтение в большом масштабе: хорошая производительность, но только после синхронизации платформ​

Используя запросы TPC-H на больших тестовых наборах данных, мы выяснили: как только данные становятся доступны и актуальны, запросы к этим таблицам Iceberg из Snowflake выполняются достаточно быстро для любого разумного аналитического процесса. Databricks, управляющий этими данными, тоже выполняет запросы к ним быстро.

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

Запись и изменения в большом масштабе: узкое место в вычислениях​

Когда множество изменений вносит Snowflake — создаёт таблицы, обновляет метаданные, формирует множество коммитов Iceberg, — задание выполняет запрос к исходным объектам Databricks. Запрос может занять вдвое больше времени, зато данные синхронизируются между обеими платформами. Ограничивающим фактором становится пропускная способность записи. В нагрузке, характерной для dbt, — множество операций с небольшими и средними таблицами вместо одного огромного добавления данных — это может замедлять запуски и порой делать их нестабильными при конкуренции за ресурсы. Иногда это приводит к явным сбоям с сообщениями о том, что ваша таблица больше не существует.

Когда же изменения вносит Databricks, запись работает так же, как в любом обычном рабочем процессе Databricks. Сложность заключается в способности Snowflake отражать эти изменения.

Главный вывод: с ростом масштаба растёт и задержка обновления​

CLD обещают быструю синхронизацию. Мы выяснили, что на малых и средних масштабах это в целом соответствует действительности. Однако при больших масштабах изменения, внесённые в Databricks, могли синхронизироваться гораздо дольше заявленного. Обычно ожидание автоматического обновления оказывалось вдвое дольше ожидаемого. Когда мы увеличили число таблиц до 500 тысяч, простейший INSERT в Databricks мог отразиться в Snowflake лишь через два дня. Некоторые таблицы словно «застревали». Со временем мы научились вручную принудительно обновлять отдельные объекты — то есть экспериментировать с настройками обновления, чтобы расшевелить систему. Но предсказать, когда изменения данных попадут из Databricks обратно в Snowflake, оказалось трудно (хорошая новость: мы слышали, что замечательная команда Snowflake уже готовит улучшения удобства работы). В основном мы ориентировались на интуитивное ощущение того, когда данные наконец появятся.

Обдумав свой опыт, мы пришли к выводу: ответ на вопрос, стоит ли внедрять Snowflake CLD и как именно это делать, зависит от масштаба и допустимой задержки:

  1. Сколько таблиц Iceberg вы синхронизируете между несколькими движками?
  2. Требуют ли ваши рабочие процессы, чтобы Snowflake отображал состояние таблиц Iceberg под внешним управлением почти в реальном времени? Или вы можете воспринимать его как представление, данные в котором могут устаревать, принять согласованность в конечном счёте и обходиться без чётких гарантий, если не разработаете собственный регламент ручных действий и систему мониторинга?

Сложности совместимости: почему дело не только в метаданных​

Быстро проявились две проблемы, не связанные с производительностью:

  • Различия в правилах именования, заключения идентификаторов в кавычки и использования регистра создают сложности, когда dbt генерирует объекты, которые два движка должны интерпретировать одинаково. Углублённое исследование подсказало нам, как dbt мог бы скрыть эти неудобства за уровнем абстракции. В будущем пользователям не придётся запоминать правила регистра и кавычек для каждой комбинации каталога и движка. Пока же, к сожалению, это неизбежная цена независимости от платформ.
  • Метаданные и особенности обновления становятся частью вашей работы. Вы управляете не только таблицами, но и системой, которая решает, когда таблицы «существуют». К тому же запросы show iceberg tables выполняются медленно.

Итоги​

CLD работают — до определённого предела. Они решают регулярно возникающие проблемы поддержания связанности данных между платформами. Если число таблиц или объём обновлений очень велики — порядка десятков тысяч, — этот подход перестаёт быть полезной абстракцией. То же верно, если вам нужна синхронизация записей с точностью до секунды. Но пока вы не приблизились к этому пределу, CLD действительно позволяют обращаться с внешними каталогами Iceberg как с любой другой базой данных.

Для нас это открывает весьма интересные возможности в рабочих процессах клиентов на dbt: межплатформенную сетку данных, внешние источники и, возможно, даже запуск одного и того же проекта dbt / DAG в нескольких хранилищах данных. Мы уверены, что интеграции с Iceberg будут и дальше совершенствоваться, становясь производительнее и удобнее. Достаточно взглянуть на возможности, появившиеся за последний год, — включая Snowflake CLD и встроенную поддержку управляемых таблиц Iceberg в Databricks, благодаря которым эта история вообще стала возможной, — чтобы с воодушевлением ждать следующего года.

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