#apache-spark #architecture #etl #delta-lake #data-lake
#apache-spark #архитектура #etl #delta-lake #озеро данных
Вопрос:
Цель
Предположим, вы создаете озеро данных и звездную схему с помощью ETL. Формат хранилища — Delta Lake. Одной из обязанностей ETL является создание таблиц с медленно меняющимся измерением (SCD) (кумулятивное состояние). Это означает, что каждый день для каждой таблицы SCD ETL считывает полное состояние таблицы, применяет обновления и сохраняет их обратно (полная перезапись).
Вопрос
Один из вопросов, которые мы обсуждали в моей команде: должны ли мы добавлять временное разделение в таблицы SCD (полная перезапись)? Означает, должен ли я сохранять последнее (полное) состояние таблицы в SOME_DIMENSION/
или в SOME_DIMENSION/YEAR=2020/MONTH=12/DAY=04/
?
Соображения
С одной стороны, Delta Lake обладает всеми необходимыми функциями: перемещение во времени и ACID. Когда он перезаписывает всю таблицу, происходит логическое удаление, и вы по-прежнему можете запрашивать старые версии и выполнять откат к ним. Таким образом, Delta Lake практически управляет временным разделением для вас, код становится проще.
С другой стороны, я сказал «почти», потому что IMHO time-travel amp; ACID не охватывают 100% случаев использования. У него нет понятия времени прибытия. Например:
Пример (когда вам нужно временное разделение)
Команда BA сообщила, что SOME_FACT/YEAR=2019/MONTH=07/DAY=15
данные повреждены (факты в любом случае должны храниться с разделением по времени, потому что данные обрабатываются по времени поступления). Чтобы воспроизвести проблему в среде разработки / тестирования, вам нужны исходные данные 1 таблицы фактов и 10 таблиц SCD.
С фактами все просто, потому что у вас есть необработанные входные данные в озере данных. Но с инкрементным состоянием (таблицами SCD) все усложняется — как получить состояние 10 таблиц SCD на момент SOME_FACT/YEAR=2019/MONTH=07/DAY=15
обработки? Как сделать это автоматически?
Чтобы еще больше усложнить ситуацию, ваша среда может пройти через кучу исправлений и повторных обработок истории. Означает, что данные 2019-07 могут быть переработаны где-то в 2020 году. И Delta Lake позволяют выполнять откат только на основе обработки или номера версии. Итак, вы на самом деле не знаете, какую версию вам следует использовать.
С другой стороны, с разделением по дате вы всегда уверены, что SOME_FACT/YEAR=2019/MONTH=07/DAY=15
оно было рассчитано заново SOME_DIMENSION/YEAR=2019/MONTH=07/DAY=15
.
Ответ №1:
Это зависит, и я думаю, что это немного сложнее.
Некоторый контекст сначала — Delta дает вам путешествие во времени, ограниченное только текущей историей фиксации, которая по умолчанию составляет 30 дней. Если вы выполняете оптимизацию, это время может быть значительно короче (по умолчанию 7 дней). Кроме того, вы действительно можете запрашивать дельта-таблицы на определенное время, а не только версию, но из-за вышеуказанных ограничений (если вы не готовы платить за производительность и финансовые затраты на хранение действительно длинной истории фиксации), это бесполезно в долгосрочной перспективе.
Вот почему очень распространенной архитектурой озера данных сейчас является подход с таблицами-медальонами (бронза-> Серебро-> Золото). В идеале я хотел бы хранить исходные исходные данные в «бронзовом» слое, иметь всю историческую перспективу в серебряном слое (уже чистый, проверенный, лучший источник истины, но со всей историей по мере необходимости) и использовать текущую версию непосредственно из «золотых» таблиц.
Это позволит избежать увеличения сложности запросов к SCDS из-за дополнительных разделов, в то же время предоставляя вам возможность «вернуться» к серебряному слою, если возникнет необходимость. Но это всегда компромиссное решение — в любом случае, не полагайтесь на Delta для долгосрочного управления версиями.
Комментарии:
1. прежде всего, спасибо за ваш ответ. Вы имеете в виду, что «Серебряная» зона будет иметь
SOME_DIMENSION/YEAR=2019/MONTH=07/DAY=15/<files>
подход к разделению, а «Золотая» — только к последнему разделуSOME_DIMENSION/<files>
? Я думаю, что это имеет смысл только тогда, когда у вас есть архитектура Lakehouse и самообслуживание пользователей по таблицам Delta Lake. У вас по-прежнему будет вся сложность запроса SCD в «Серебряной» зоне, где происходит вся логика ETL. Преимущество только для пользователей «золотой» зоны (бизнес). ETL вообще не будет читать «Золотой». В моем случае у меня есть «Золотой» слой в хранилище данных2. также вы можете запрашивать дельту по времени, но это время обработки. В то время как таблицы разделены по времени прибытия :
SOME_DIMENSION/YEAR=2019/MONTH=07/DAY=15/<files>
. Из-за повторной обработки эти два раза могут не совпадать3. Один момент, под разделением вы подразумеваете хранение нескольких дельта-таблиц в разных папках со структурой, основанной на времени?
4. одна дельта-таблица, но каждый раздел будет содержать полную копию данных. Одна таблица упрощает управление метаданными.
5. Хорошо, так что да и нет — я бы хотел получить последнее представление в DW, всю историю в «серебряной» зоне, но не обязательно в полной копии для каждого формата раздела, поскольку это может привести к проблемам позже, когда система растет и обработка выполняется чаще. В идеале мы могли бы иметь все версии данных в таблице, но только в том случае, если они действительно менялись между поступлениями, и иметь разделение, которое наилучшим образом поддерживает большинство распространенных запросов (вероятно, сначала с помощью чего-то вроде переключателя «isActive»).