Большинство ETL-конвейеров извлекают данные из реляционных баз в пакетном или микропакетном режиме. Читайте далее, по каким шаблонам реализовать операции извлечения.
Моментальные снимки: периодическая выгрузка данных из исходных таблиц
Полная периодическая выгрузка данных из одной или нескольких таблиц – это, пожалуй, самый простой метод извлечения изменяемых данных. По своей сути результат полной выгрузки представляет собой так называемый полный моментальный снимок, фиксирующий состояние базы данных на конкретный момент времени. Он очень прост для реализации и довольно эффективен для небольших таблиц и нечасто изменяющихся измерений. Однако, производительность операций снижается по мере увеличения размера исходной таблицы, и не сохраняется история изменения данных, поскольку каждый раз при выполнении конвейера извлечения происходит перезагрузка данных.
Вместо создания полного моментального снимка, что занимает много времени на большой базе данных, можно делать это частями, ограничив период извлечения. Например, извлекать только данные за последние несколько месяцев. Разумеется, этот шаблон извлечения требует наличия отметки времени для фильтрации последних записей. Так можно избежать многократного извлечения больших неизмененных исторических данных. Такой метод довольно эффективен для небольших и средних таблиц со множеством исторических записей. Но он предполагает дополнительные операции вычисления дублей и обеспечения согласованности данных по сравнению с методом полного моментального снимка. Кроме того, изменение и удаление данных фиксируется только за охватываемый период. Этот подход основан на наличии столбца отметки времени изменения в исходной таблице, который всегда должен быть корректен при добавлении или изменении записи в источнике. Также при реализации этого метода может потребоваться проверка схемы данных.
На практике метод неполного моментального снимка подходит для использования в сценариях, где большая таблица разделяется по месяцам, и использование месяца в качестве предиката может ускорить операцию извлечения, чем группировка по отметке времени. Также этот способ подходит, если данные в источнике могут быть изменены вручную: тогда просто надо извлечь данные с более длительным сроком хранения.
В заключение разговора про моментальные снимки отметим, что можно делать полный моментальный снимок и сохранять результат в отдельном репозитории, указав версию создания. Так можно отслеживать историю изменения данных. Часто этот подход реализуется в виде отдельного конвейера для сохранения текущего состояния исходных таблиц в отдельном наборе данных. При этом в итоге будет сохранено два набора данных: один содержит всю историю с повторяющимися данными, а другой — содержит только текущее состояние БД. Таким образом, часть данных в разных репозиториях будет дублироваться, занимая место на дисковом пространстве. Поэтому придется применять такие политики хранения, чтобы периодически удалять старые данные для освобождения места. Кроме того, операция создания моментального снимка на больших объемах данных выполняется довольно долго. Таким образом, этот метод не подходит для больших и быстро меняющихся наборов данных или измерений.
Инкрементные вставки
Инкремент означает изменение исходной таблицы относительно предыдущего состояния. На практике инкрементный ETL-конвейер часто используется для классического DWH. Но для озера данных он не считается подходящим из-за невозможности обновления данных и выявления измененных данных в больших таблицах. Подробно об этом мы писали здесь.
Если исходная таблица является неизменяемой, например, Append Only в Greenplum, операций обновлений и модификаций с ней не производится. При наличии инкрементного идентификатора строки, например, целочисленного первичного ключа или отметки времени вставки, извлечь новые записи можно с помощью этих столбцов. Это очень простой метод, который позволяет отслеживать последнюю извлеченную запись из источника. Он не увеличивает нагрузку на исходную базу данных и отлично подходит для больших неизменяемых наборов данных, например, логов событий. Однако, при использовании этого метода важно обеспечить постоянную правильность столбца-идентификатора. Кроме того, такой подход не позволяет зафиксировать удаления.
Итак, инкрементные вставки в целом хорошо работают с неизменяемыми данными. Впрочем, для изменяемых данных, если в исходной таблице есть столбец отметки времени изменения, такой подход тоже можно использовать для добавления новых и измененных записей в корпоративное озеро или хранилище данных. Но вместо вставки необходимо выполнить обновление целевого набора данных, чтобы исключить дубликаты, например, с помощью SQL-оператора UPSERT.
Такой подход не нагружает систему-источник, поскольку извлекаются только новые и измененные записи. Также метод подходит для больших и быстро меняющихся таблиц, что важно для стека Big Data. Но в конвейер придется добавить дополнительную логику для дедупликации и замены измененных записей в целевом наборе данных. Это можно сделать, используя современные форматы таблиц, такие как Apache Hudi, Iceberg или Paimon, о котором мы недавно писали здесь. Поскольку метод инкрементных вставок с UPSERT основан на предположении, что измененный столбец временной метки всегда обновляется при изменении записи, это необходимо обеспечить для его корректной работы. Кроме того, он не фиксирует операции удаления, поэтому их отслеживание следует реализовать дополнительно.
В заключение рассмотрим способ, который комбинирует инкрементные вставки с периодической выгрузкой. Это подходит для сценария, когда нужно выполнить инкрементную вставку или обновление, но нельзя полностью доверять столбцу с идентификатором или отметкой времени изменения. В таком случае можно инкрементные вставки выполняются периодически для извлечения новых или обновленных данных. А полный или частичный моментальный снимок создается реже, чтобы отследить отсутствующие или устаревшие записей, полученных с помощью инкрементных вставок. При этом есть риск несогласованности инкрементных данных до момента создания моментального снимка. Несмотря на это, такой вариант может быть жизнеспособным в средах, где возможно ручное изменение записей в исходной системе. Он не слишком нагружает источник, если не делать часто полных моментальных снимков больших таблиц, а также устраняет риски нарушения целостности данных, связанные с инкрементной вставкой или обновлением. Но подобный способ более сложен с точки зрения реализации из-за необходимости управлять двумя отдельными конвейерами и зависимостями между ними, что мы недавно разбирали в этой статье.
Узнайте больше про архитектуры данных и конвейеры их обработки на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники