Мы начали с простой цели: разобраться в небольших операционных данных из нашей среды Oracle E-Business Suite (OEBS). Сначала всё казалось несложным. У нас был классический Data Warehouse: пакетная обработка, массовые загрузки и привычная реляционная СУБД. Но по мере того как мы углублялись в проект, казалось бы рутинная задача превратилась в исследование и эксперименты с неожиданными поворотами и поиском чего-то действительно универсального.
Пакетная обработка против Near Real-Time
Наш изначальный сценарий — классический Oracle Data Warehouse, который наполняется данными из OEBS партиями, с запуском ночных трансформаций и долгосрочной аналитикой на относительно стабильных наборах данных. Такой подход отлично подходил для исторических отчётов, но не удовлетворял растущую потребность в более оперативной (NRT) аналитике. Бизнес хотел получать ответы намного быстрее — не дожидаясь, пока «чернила высохнут» на вчерашних отчётах.
Так мы пришли к Change Data Capture (CDC) — методу, который отслеживает и фиксирует изменения (INSERT, UPDATE, DELETE) в базе данных в режиме реального (или почти реального) времени. Вместо того чтобы каждый раз заново обрабатывать весь набор данных, CDC позволяет выделять только изменения и передавать их в другие системы (хранилища данных, аналитические платформы и т.д.). Мы использовали инструменты с открытым исходным кодом, настроив CDC-конвейеры из Oracle в PostgreSQL при помощи Kafka Connect. Это позволило не только реализовать near real-time CDC, но и избавило нас от необходимости покупать лицензии на Oracle для нужд нашего хранилища данных, обеспечив и экономию, и технологическую гибкость.
Мы добились задержки в 30 секунд при репликации данных. Для краткосрочных очетов для онлайн данных это было отличным результатом. Но запросы на более длительные периоды инициировали длительный перекур.
Возникла дилемма: реализовывать lambda архитектуру с пакетной и онлайн обработкой или искать альтернативу? Мы решили покапать глубже, ибо трансормированные данные имеют проблему с гибкостью.
Намёк на универсальность
Вместо того чтобы возвращать хотя бы и частично пакетную обработку, мы решили продолжить поиск. Нашей мечтой стало «универсальное» аналитическое решение, которое одинаково хорошо работало бы и для краткосрочных, и для исторических запросов.
Мы обратили внимание на облачные проприетарные колоночные хранилища. Они обещали высокую скорость и масштабируемость, но есть небольшая проблема. Постоянная загрузка CDC-данных в колоночный формат инициирует множество перестроек колоночного хранилища. Одно обновление может инвалидировать большую часть данных. Это похоже на попытку каждый раз перестраивать всю библиотеку, когда появляется новая книга - ставим новый стелаж и перегружаем книги из старого и переиндексируем каталог, очередь на абонементе — толпа растёт.
Некоторые вендоры предлагали гибридные форматы (HTAP), которые на первый взгляд выглядели привлекательно, универсальность OLAP/OLTP. Но все это вызывало вопросы по производительности и снова же — риск привязки к конкретному поставщику (vendor lock).
И тут мы наткнулись на Iceberg — открытый табличный формат. Это некий нейтралитет: его можно было разворачивать локально, в разных облаках, и использовать совместно с различными системами вычислений. Плюс ко всему, Iceberg поддержка из коробки time travel.
Отсутствующий элемент: упрощённая миграция и CDC
Однако переход на Iceberg не был безоблачным. Миграция данных и CDC в Iceberg могли оказаться нетривиальными: GoldenGate — усложнение системы, плюс GoldenGate не дешево. SPARK - пакетная обработка. Нам хотелось чего-то более простого. Но сначала надо было проверить производительность Iceberg, сравнить например с Oracle и Postgres.
Мы закатали рукава и написали Ora2Iceberg — собственный CLI-инструмент, который льет данные из Oracle в Iceberg хранилище. С помощью Ora2Iceberg теперь можно было напрямую выгружать данные из Oracle в любую открытую среду для аналитики.
Ora2Iceberg — opensource проект, доступный на GitHub (подробности — на официальном сайте). Мы используем его для миграции данных. Хотя Ora2Iceberg не является классическим решением для CDC, он подходит для сценариев, где данные неизменяемы или могут быть извлечены повторно с помощью полей типа LAST_UPDATE_DATE
в секции WHERE
. Этот фреймворк даёт возможность без проблем переносить данные из Oracle в разные системы хранения: локальные файловые системы, Ozon, MinIO, AWS S3 и т.д.
Стоит отметить, что в AWS S3 данные легко интегрировать с AWS Glue, что позволяет Snowflake обращаться к «каталогизированным» в Glue данным и напрямую работать с таблицами Iceberg. Такая связка упрощает работу с данными и подводит нас к идее более унифицированной и гибкой аналитической экосистемы. Прощай Vendor Lock.
Oracle, PostgreSQL, Athena и Snowflake на одних и тех же данных
Мы решили провести масштабный эксперимент. Для упрощения выбрали S3 в качестве общего «слоя хранения» для облачных движков и сравнили производительность четырёх разных систем: Oracle, PostgreSQL, Athena и Snowflake. Все они работали на одном и том же универсальном наборе данных.
Данные представляли собой десятилетний срез из OEBS — сложный SQL-запрос, включающий три union’а, каждый из которых объединял по 5–6 таблиц, с датами в WHERE
. Oracle и PostgreSQL в некотором смысле имели «фору» в виде нативных оптимизаций и реляционной природы. Iceberg выступал как новичок, без партиционирования, да ещё и с decimal(38,10)
- колонками (наследие Oracle NUMBER), что усложняло жизнь движкам. В облаках мы запускали Athena (serverless, от Amazon) и Snowflake (X-Small warehouse, но «колоночная» аналитика). Мы не знали, чего ожидать, — и это было слегка волнительно.
Результаты теста

Время выполнения SQL в разных системах
-
Snowflake и Athena работали почти «линейно» — словно опытные марафонцы, спокойно обрабатывая большие объёмы данных.
-
PostgreSQL и Oracle были скорее спринтерами: быстро стартовали на небольших запросах, но теряли скорость на крупных объёмах.
Визуализация производительности

Время выполнения в зависимости от числа строк (логарифмическая шкала). Snowflake и Athena масштабируются почти линейно, PostgreSQL и Oracle сильно «проседают» с ростом объёма.

-
Те же выводы, просто другая визуализация.

-
Относительная производительность. Snowflake и Athena стабильны, PostgreSQL и Oracle ведут себя немного непредсказуемо.

-
Размах Времени Исполнения. Показывает распределение времени выполнения запросов, подчёркивая вариативность в разных системах.
Следующая глава
На этом наше путешествие не заканчивается. С появлением Ora2Iceberg миграция упростилась; теперь мы хотим развивать поддержку других каталогов и тестировать движки вроде Presto, Trino и DuckDB. Эксперименты продолжаются, и мы обязательно поделимся результатами. Также в планах — реализовать near real-time CDC из Oracle в Iceberg, чтобы объединить краткосрочную и долгосрочную аналитику в единый, элегантный процесс.
Автор: abalaban