Как эффективно найти последний раздел из набора данных S3 с помощью Spark - PullRequest
0 голосов
/ 27 мая 2019

У меня есть набор данных, в который данные добавляются почти каждый день, и его необходимо обрабатывать каждый день в части большого ETL. Когда я выбираю раздел напрямую, запрос действительно быстрый:

SELECT * FROM JSON.`s3://datalake/partitoned_table/?partition=2019-05-20`

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

Еще одна попытка привела меня к тому, чтобы спарк нашел последний раздел этого набора данных, чтобы убедиться, что больший запрос не сработает:

SELECT * FROM JSON.`s3://datalake/partitoned_table/`
WHERE partition = (SELECT MAX(partition) FROM JSON.`s3://datalake/partitoned_table/`)

Это работает каждый раз, но невероятно медленно.

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

Есть идеи, как это сделать правильно?

Ответы [ 2 ]

2 голосов
/ 27 мая 2019

(SELECT MAX(partition) FROM JSON.s3://datalake/partitoned_table/)
Этот запрос будет выполнен как подзапрос в Spark.
Причина медлительности
1. Подзапрос должен быть выполнен полностью до начала фактического выполнения запроса.
2.Выше запрос будет перечислять все файлы S3 для получения информации о разделе.Если в папке много файлов, этот процесс займет много времени.Время, затрачиваемое на листинг, прямо пропорционально количеству файлов.

Мы могли бы создать таблицу поверх s3://datalake/partitoned_table/ со схемой разбиения, скажем, имя таблицы tbl
Вымог бы выполнить
ALTER TABLE tbl RECOVER PARTITIONS
, который хранит информацию о разделах в metastore.Это также включает в себя листинг, но это однократная операция, и искра порождает несколько потоков для выполнения листинга, чтобы сделать его быстрее.

Тогда мы можем запустить

SELECT * FROM tbl WHERE partition = (SELECT MAX(partition) FROM tbl`)

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

1 голос
/ 27 мая 2019

WorkAround, когда у вас нет Hive-

FileSystem.get(URI.create("s3://datalake/partitoned_table"), conf).listStatus(new Path("s3://datalake/partitoned_table/"))

Выше кода даст вам список файловых разделов example - List(s3://datalake/partitoned_table/partition=2019-05-20, s3://datalake/partitoned_table/partition=2019-05-21....)

Это очень эффективно, потому что это только выборка метаданных из местоположения s3.

Просто возьмите последние разделы файла и используйте его в качестве SQL.

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