Если вопросы о том, зачем нужна интеграция данных, в чем различия ETL и ELT, как правило уже не требуют пояснений и ответов, и очевидны почти всем, то вопросы о том, какой именно Extract - Load сервис использовать, в чем различия между разными решениями, и как не прогадать в долгосрочной перспективе я слышу гораздо более часто.

В этой публикации попробую резюмировать свои знания:

  • Каталог поддерживаемых источников и приемников данных.

  • Метод чтения данных из источников (Extract).

  • Способы репликации в целевое Хранилище (Load).

  • Работа с изменениями структуры данных (Schema Evolution).

  • Трансформации перед загрузкой данных (EtLT).

  • Тип развертывания решения (Deployment).

Буду объяснять и показывать примеры на сервисах, которые использовал сам: Hevo Data, Fivetran, Airbyte. Однако критерии универсальны и применимы для любых других систем подобного класса.

Каталог поддерживаемых источников данных

Это самое главное. Наличие коннекторов к базам данных и бизнес-приложениям - это то, ради чего мы вообще рассматриваем использование того или иного решения для интеграции данных. Если источник не поддерживается - использовать такой сервис бессмысленно.

Поэтому прежде чем приступить к оценке вендоров, составьте список систем-источников, данные из которых вы хотели бы реплицировать в Хранилище Данных. В моём случае список выглядит примерно так:

  • Databases:

    • PostgreSQL (CDC)

    • MongoDB (CDC)

  • Events (Webhooks):

    • Web / Mobile events (Snowplow)

    • Github events

    • Custom events (callbacks)

  • Apps:

    • Google Analytics

    • Google Sheets

    • Open Exchange Rates

    • Braze

    • Intercom

    • Jira

  • Storage

    • AWS S3

Hevo Data Source Catalog
Hevo Data Source Catalog

Также не забывайте и про поддерживаемые приемники данных. Сегодня вы можете пользоваться BigQuery, но завтра может возникнуть срочная необходимость переехать на Clickhouse.

Тип развертывания решения

От него зависит, какую долю ответственности за функционирование системы вы будете брать на себя (или команду Operations / SRE).

Коротко, возможны следующие варианты:

1 SaaS – полностью управляемый сервис

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

2. Self-hosted

Вы и ваша команда полностью ответственны за работоспособность сервисов и подсистем. У вас есть доступ к коду, конфигурации и ресурсам, которые вы назначаете для сервиса. Однако это же и недостаток, ведь именно вам и придется всё это поддерживать в работоспособном состоянии.

3. Гибридное решение

Этот подход предполагает использование готовых сервисов в качестве элементов и подсистем. Например, использование AWS RDS (Relational Database) в качестве Metadata DB, AWS MSK (Managed Kafka) в качестве распределенной очереди сообщений, AWS EKS (Managed Kubernetes) для контейнерной оркестрации.

Airbyte Deployment types
Airbyte Deployment types

Как правило, чем большую ответственность вы возлагаете на сторонний сервис, тем больше придется заплатить, однако это правило работает не всегда. Например, для поддержки решения вам может понадобиться нанять еще одного человека на роль SRE, что может обойтись значительно дороже использования SaaS-сервиса.

Оценивайте это как trade-off между ресурсами специалистов в команде и денежными затратами.

Метод чтения данных из источника

Существует несколько способов регулярно получать данные из источников. Они отличаются в объеме затрачиваемых ресурсов, скорости обновления, возможности получать все изменения (включая удаление строк и изменение структуры таблиц).

1. Full-refresh

Чтение таблицы с исходными данными на источнике полностью каждую синхронизацию данных.

2. Incremental

Чтение таблицы полностью первый раз. Чтение только дельты (изменения) каждый последующий раз. Такой способ позволит значительно сократить нагрузку на систему-источник и ускорить процесс репликации данных. Однако для этого способа уже необходим ключ записи (Primary Key) и атрибут-курсор, согласно которому будет выделяться дельта (например, timestamp изменения строки).

Airbyte Replication Modes
Airbyte Replication Modes

3. CDC (Change Data Capture)

Предполагает чтение лога СУБД, а не самих таблиц. Способ позволяет получать все изменения состояния (включая удаление строк), а также модификации схемы, однако уже гораздо более сложен в инсталляции. Это предпочтительный способ репликации для большинства реляционных баз данных.

CDC vs Standard sync
CDC vs Standard sync

Способ репликации в приемник данных

Выгрузить данные из источника - это только первая часть работы (Extract). Не менее важной часть является загрузка данных в Хранилище (Load). Сделать это тоже можно несколькими способами:

1. Overwrite

Полная перезапись целевой таблицы в СУБД-приемнике данных. Это самый простой, и в то же время самый затратный способ. Однако затраты минимальны при условии, что реплицируется небольшой справочник, который нет необходимости версионировать (отслеживать изменения).

2. Append

Запись новых наборов записей к уже имеющейся таблице. Технически это вставка (INSERT) данных. В результате такой репликации в целевой таблице появляется множество записей по одному ключу, которые отражают историю изменений (атрибутного состава, например). Исходя из истории изменений можно отслеживать темпоральность (привязку ко времени) атрибутного состава сущностей. Иначе это можно назвать организацией Slowly Changing Dimensions (SCD).

3. Deduped history (Snapshot)

Целевая таблица отражает актуальное состояние записи на текущий момент (Snapshot). Таким образом, вместо множества строк, отражающих разные состояния сущности во времени, у вас будет одна строка, соответствующая последнему (актуальному на момент сейчас) состоянию сущности.

На рисунке ниже схематично изображены различия между Append и Deduped History.

Append mode vs Deduped History Airbyte
Append mode vs Deduped History Airbyte

Extract-Load сервисы, которые вы будете рассматривать могут поддерживать различные стратегии, либо их вариации. При выборе исходите из требований к аналитическим решениям: необходимо ли вам сохранять историю изменений или нет, будете ли вы самостоятельно строить актуальные снимки (snapshots) из истории этих изменений, либо вы хотите получить их в готовом виде в результате работы сервиса интеграции данных.

Изменения в структуре данных источника (schema evolution)

Отлично. Предположим, к данному этапу вы настроили пайплайны репликации данных и всё функционирует корректно. Однако ничто не статично, и наши источники со временем начинают меняться.

  • Добавление новых атрибутов (колонок).

  • Изменение типов атрибутов (INT -> FLOAT, VARCHAR(128) -> VARCHAR(512)).

  • Переименование атрибутов (колонок).

  • Удаление атрибутов (колонок) из таблицы-источника.

Изменения такого рода могут быть отработаны в автоматическом режиме (как в Fivetran), либо запрашивать явные подтверждения к изменениям в маппинг (возможно, вы захотите пропустить новую колонку и не загружать её в DWH).

Я рекомендую заранее подготовить список возможных сценариев и протестировать то, каким образом сервис будет реагировать на данные сценарии. Например, когда-то я пользовался таким набором сценариев (упрощенно):

Сценарий

Что тестируем

Load 1 small table

Connectivity, Mapping, Target objects creation

Load 1 large table (CDC)

Load testing, Throughput, Bandwidth throttling

Loading multiple tables

Performance, Multi-threading, Ease of use, Field mapping

Delete records

How DELETEs are handled?

Add fields to collections

How changing data is handled?

Change field type

How changing data is handled?

Cause errors (eg. numeric overflow)

Logging, Error debug, Restream

Мониторинг и состояние системы

Быстро и удобно найти причину проблем, когда что-то ломается или идёт не так - очень важно. Поэтому обращаем внимание на интерфейс системы и возможность получения уведомлений по удобным каналам.

1. Интерфейс и приборная панель

Web GUI с дашбордом, глядя на который получаем представление о статусе и работоспособности системы. А также о важнейших индикаторах и показателях:

  • Количество событий (Ingested, Loaded).

  • Детализация по таблицам-источникам.

  • Маппинги, которые требуют внесения изменений.

  • Latency (время от чтения до загрузки данных).

2. Доступ к логам сервиса

  • История изменений в конфигурации.

  • Детальные сообщения об ошибках.

  • Лог загрузки данных (сколько, когда, откуда и куда).

3. Уведомления об ошибках и инцидентах

В Slack и на почту.

Возможность применять трансформации к данным перед загрузкой

Хотя я всецело поддерживаю подход ELT в противовес ETL, необходимость делать ряд простых преобразований может быть насущной в ряде случаев:

1. Пропуск атрибутов (колонок)

Пропуск колонок с персональными данными (PII). Они просто никогда не должны быть загружены в DWH.

Более сложный вариант - загрузка значений только для ряда записей (например, только для сотрудников компании), в остальных случаях значения должны быть NULL.

2. Применение простых функций

  • Хеш-сумма (с солью) вместо значений телефона, почтового адреса.

  • Email domain вместо исходного значения адреса.

  • Код страны по номеру телефона.

  • Длина смс-сообщения в символах (вместо исходного текста).

3. Валидация данных перед загрузкой

  • Допустимые значения (целочисленные, текст без спецсимволов и т.д.).

  • Ограничения по максимально допустимой длине строки (например, в Amazon Redshift максимум 65535 символов).

  • Проверка на валидный JSON-документ (XML).

Очень поможет панель, где вы сможете протестировать код преобразований на реальных примерах событий, прежде чем публиковать код в production.

Такой подход можно назвать EtLT, где t это tweak - простые, легковесные преобразования.

Ряд других более узконаправленных требований

На которые тоже стоит обратить внимание:

  • Регион развертывания сервиса (Availability Zone).

В идеале источник, EL-сервис и DWH должны находиться в одном регионе, например eu-central-1 Europe (Frankfurt). Плохо, если ваши данные совершают путешествие за океан и обратно прежде чем попадают в Хранилище Данных.

  • Загрузка событий из источника с определенного момента времени (не с начала).

Актуально для огромных таблиц, для которых нужно перезагрузить, например, только последний месяц или неделю данных, но не всю историю.

  • Pipelines as Code.

Представьте, что у вас порядка 10-15 источников с 10-50 сущностей (таблиц) в каждом. Я, честно говоря, устаю долго и рутинно кликать галочки мышкой. Возможность конфигурировать пайплайны как код (Pipelines as Code) - это то, что может стать killer feature или решающим фактором в использовании того или иного сервиса.

Этим особенностям и многим другим знаниям, связанным с современной и удобной организацией работы с данными я и мои коллеги учим на занятиях Analytics Engineer и Data Engineer в OTUS.

Это не просто набор занятий по темам, а единая, связная история, в которой акцент делается на практические навыки, так необходимые компаниям-работодателям. На live-сессиях мы делимся своим опытом и реальными кейсами:

  • Организация Хранилища Данных и Data Lake.

  • Продвинутое моделирование в dbt.

  • Аналитические паттерны и SQL.

  • DataOps-практики: Оркестрация, CI-CD, Data Quality, Monitoring.

  • Кейсы: Сквозная аналитика, Company's KPI, Timeseries analysis.

Также своими наблюдениями, опытом и практиками я делюсь в ТГ-канале Technology Enthusiast.

Напишите комментарий, если имеете опыт в выборе Extract - Load сервиса. Что смотрели, что выбрали, по каким критерям, и каков результат сегодня?

Спасибо!

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


  1. ChidoriAmi
    15.11.2022 19:15
    +1

    Очень доступно изложено о том, какие подводные камни надо прощупать перед проектированием DWH. Я бы добавила телеграм как способ оповещения (уже много где поддерживается).

    Также стоит учитывать при выборе и проектировании, как сильно может вырасти система (горизонтальное масштабирование). Пример: в известном банке загрузка дневного регламента была реализована сначала в одном управляющем workflow (потоке) в Информатике. Т.е. отдельные процессы, конечно, были реализованы как отдельные workflow, а в управляющий встраивались "ссылки", которые вызывали загрузки в правильном порядке. Управляющий поток буквально за год так разросся, что при любых действиях с ним интерфейс Информатики зависал минут на 30-40 – и при запуске, и при открытии, и при любом изменении, даже банальном “протягивании стрелочки”. В общем, переделывать потом пришлось на несколько маленьких потоков и костылить прикручивать между ними взаимосвязи.

    Также интересный вопрос, как решение будет работать с несколькими процессами над одним объектом. Например, я возьму и запущу две загрузки в одну и ту же таблицу за разные периоды (инициирующую/исправляющую и регламентную, например) - по идее, система не должна такого позволять вообще или должна выстраивать их в очередь (вторая не стартует, пока первая не добежит).

    Мы у себя выбрали смешанное решение - ETL-инструмент (Datastage, да, то еще г, так уж вышло) выступает как движок, умеющий выполнять операции разного рода. А логика уже на нашей системе. Описание, если интересно, тут


    1. kzzzr Автор
      15.11.2022 22:48

      Дельные дополнения.
      И да, скорее публикация ориентирована на маленькие-средние компании. С крупными предприятиями всегда есть нюансы. Читая, вспомнил и свой опыт работы с Informatica PC, кажется, в том же Банке :)
      Спасибо за то, что делитесь опытом!