Как решить проблему чрезмерных затрат на запись больших двоичных объектов Azure ADF / Databricks в Data Lake Gen2

Я сравниваю разные способы загрузки пара файлов JSON в Data Lake Gen 2 с паркетными файлами, но в каждом протестированном сценарии затраты на хранение больших двоичных объектов являются чрезмерными, прогнозируемыми в тысячи долларов в месяц из-за «операций горячей записи» (перечисленных в blob биллинг).

сценарий ежедневной нагрузки:

  • 150 многострочных файлов JSON, каждый по 1К сообщений
  • Предварительно установленный 5-значный ключ раздела для вертикального разделения.

Результаты одинаковы вне зависимости от метода: потоки сопоставления фабрики данных, синапсы и блоки данных: операции с большими двоичными объектами стоят в 3-5 раз дороже, чем сами вычисления. Даже при запуске в одном пакете для каждого ключа вертикального раздела создается несколько паркетных файлов. Конечно, со временем это нужно будет сжать, чтобы оптимизировать производительность чтения, но уже непосредственные затраты на запись вызывают вопросы о подходе.

Вот пример кода Databricks:

file_location = "abfss://files@<storageaccountname>.dfs.core.windows.net/<foldername>/*.json"
df = spark.read.option("multiline", "true").json(file_location)
df.repartition('PartitionKey')
df.write.partitionBy('PartitionKey').parquet('abfss://files@<storageaccountname>.dfs.core.windows.net/Results)

Блокнот Synapse почти такой же, как и выше. В потоке сопоставления фабрики данных это простое преобразование из JSON в Parquet без каких-либо других шагов. Мне пришлось использовать Mapping Flow, поскольку стандартное копирование не поддерживает разделы.

Тестовый пример обрабатывает 150 файлов за один раз, но в реальной жизни это будет в среднем 7 файлов в час, что делает решение более склонным к созданию большего количества небольших файлов в течение дня.

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


comment
Как часто вы это делаете? Вы хотите сказать, что ваша операция переразбивки генерирует 150 файлов за один прогон?   -  person Jason Horner    schedule 10.11.2020
comment
Привет, @Jason Horner, при разбиении на разделы генерировалось 80 тыс. Разделов (5-значный ключ раздела) из 150 тыс. Сообщений, и это приводило к чрезмерным операциям горячей записи с большими двоичными объектами, что приводило к высоким транзакционным издержкам. После изменения разделения на год / месяц / день количество операций горячей записи с большими двоичными объектами было сокращено более чем в 600 раз. Меньшее количество файлов лучше выполняло тесты производительности чтения даже до сжатия (поскольку в целом файлов было меньше). Спасибо за предложение   -  person Rich750    schedule 14.11.2020


Ответы (2)


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

person Saz    schedule 09.11.2020
comment
Привет, @Saz, слишком много разделов вызывали тяжелые операции с большими двоичными объектами, даже если они были запущены в конце дня. Несмотря на то, что все было продуктивно (запись и чтение), это сопровождалось затратами на скрытые операции с большими двоичными объектами из-за количества разделов. - person Rich750; 14.11.2020

Высокая стоимость эксплуатации хранилища была вызвана слишком большим количеством разделов. Изменение стратегии разделения привело к резкому сокращению операций ввода-вывода и затрат.

person Rich750    schedule 13.11.2020
comment
Рады узнать, что ваша проблема решена. Вы можете принять его как ответ (нажмите на галочку рядом с ответом, чтобы переключить его с серого на заполненный). Это может быть полезно для других членов сообщества. Спасибо. - person CHEEKATLAPRADEEP-MSFT; 16.11.2020