Мы начали с простой цели: разобраться в небольших операционных данных из нашей среды 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, чтобы объединить краткосрочную и долгосрочную аналитику в единый, элегантный процесс.

Комментарии (5)


  1. Crogs
    02.02.2025 23:48

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


    1. abalaban Автор
      02.02.2025 23:48

      Спасибо за вопрос. Конфигурация для нас была не совсем важна. Скажем так и Oracle и Postgres были в десятки раз мощнее Snowflake и Athena. Вертикальное масштабирование OLTP не даёт линейного прироста производительности. При переходе на Postgres мы неплохо сэкономили на лицензиях Oracle, и Postgres прилично справился с нагрузкой. Но мы достигли предела производительности для аналитики. Snowflake показывал прекрасные результаты по аналитике, но NRT трансляция OLTP в OLAP — дорогое удовольствие. Да и Snowflake не бесплатный. Рассматривали вариант с ClickHouse — прекрасная «молотилка», пока дело не доходит до Joins. Как вариант для ClickHouse рассматривали NRT денормализацию/материализацию. Очень интересная задача, может, когда-нибудь и займёмся. Мы не знали, чего ждать от Iceberg на сложных Joins, это и было целью эксперимента. Теперь мы доделываем CDC Oracle to Iceberg и можно ставить локально Trino и переносить Postgres Datawarehouse на Iceberg Lakehouse :-) Ну и Iceberg maintenance утилиту закончим. Про ora2iceberg почему нет - есть же ora2pg теперь есть и ora2iceberg


  1. funny_falcon
    02.02.2025 23:48

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

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

    А вот мне совершенно не понятно, как цифра в различных представлениях в статье друг с другом соотносятся.


    1. abalaban Автор
      02.02.2025 23:48

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


      1. funny_falcon
        02.02.2025 23:48

        Я нормально читаю логарифмические шкалы, у меня с этим проблем нет.