Привет знатокам Spark. У меня вопрос. У меня есть файлов CSV (обычная таблица) 400Гб в S3. Я запустил EMR+Spark. Выбрал 4 рабочих ноды r5a.4xlarge (128GB RAM каждый).

В ноутбуке создал data frame
df = spark.read.format("csv").option("header", "true").option("delimiter", '|').load("s3://redshift/intent-CSV/")

а затем создал SQL VIew и написал запрос с фильтром по тексту:

df.createOrReplaceTempView("idataset_csv")
agg_sql = """SELECT *
FROM dataset_csv
WHERE text LIKE '%music%' and locale = 'en_US'
and date between '2020-03-31' and '2020-04-05'
"""
log_aggregates_DF = spark.sql(agg_sql)
log_aggregates_DF.show()


Запрос выполнялся не очень быстро 20-40 секунд. Я хочу, чтобы он выполнялся за 1 секунду. Оперативки больше 500Gb. Я еще попробую загрузить Parquet вместо CSV - она весит 50гб вместо 400.

В общем мне нужно SQL запросы но супер быстро, что можно подкрутить? Пишите в коментах, спасибо! А я потом расскажу про кейс и добавлю похожий в курс.

35 comments

Show 1 more comment
createOrReplaceTempView creates (or replaces if that view name already exists) a lazily evaluated "view" that you can then use like a hive table in Spark SQL. It does not persist to memory unless you cache the dataset that underpins the view.

явно закешируй в память
но что-то подсказывает, что 1с для спарка - это слишком быстро.
Запросы с поиском по подстроке будут читать весь датасет в рамках подходящих партиций. У вас ведь партицированые по полю date данные? Если файлы тупо лежат рядом друг с другом, то Спарк конечно будет вынужден их все читать. Если же их сложить так, чтобы можно было отобрать для чтения только те, что относятся к диапазону дат, то будет побыстрее работать. Но в рамках диапазона дат все равно читаться будет весь диапазон из-за предиката с процентами.
Запросы такого рода можно читать или через athena или через s3-select не нужен тут спарк совсем
Ну и забудьте про 1 секунду при чтении чего-либо с s3
Присоединюсь к коллегам-> партиционирование, персист и лучше использовать lucine index(elastic ...) если ожидается поиск по тексту
Еще, как минимум нужно учитывать время на чтение из S3 в память спарк джобы. Так что 20 секунд для 400 гб это прям супер
Попробуйте через filter без создания таблиц.
AI Rust
Попробуйте через filter без создания таблиц.
на выходу хотелось бы SQL чтобы пользователи могли писать запросы.
Al T
Запросы такого рода можно читать или через athena или через s3-select не нужен тут спарк совсем
изначально была афина, запрос был 25 секунд, захотелось попробовать спарк и сократить время. Ксати Redshift за 7 секунд отрабатовал.
Al T
Ну и забудьте про 1 секунду при чтении чего-либо с s3
Еще есть вариант ElasticSearch, там быстро запросы, но надо в json все перегонять и lambda делать для ES API, и уже не SQL
Dmitry Anoshin
потому что ноды R5 - это memory optimized
Я про другое. Спарк добавляет некоторый оверхед к запросам. Сначала надо перегнать с диска (с3) в память (на нодах). Потом мастер должен распределить задания по нодам, потом собрать с них результаты. Я могу помочь с датафрейм АПИ. На пайтоне пишешь или на скала?
Dmitry Anoshin
с датафрейм?
df.filter(col(locale)=="en_US") и тд. Больше контейнеров тоже поможет. На скале будет чуть быстрее.
А надо один раз загрузить и потом быстро запросы строить или каждый раз новый s3 файл? В паркет конвертация поможет однозначно. Ну и если его один раз загрузить и много раз читать то тут чего только нет и эластик и кликхаус да и редшифт тоже хоть и по медленнее будет
Типа такого

```
df = spark.read.format("csv").option("header", "true").option("delimiter", '|').load("s3://redshift/intent-CSV/")

log_aggregates_DF = df\
.filter("text LIKE '%music%'")\
.filter("locale = 'en_US'")\
.filter("date between '2020-03-31' and '2020-04-05'")\
.cache() # <- кеширование

log_aggregates_DF.show()
```

Ну и да, на паркете возможно будет лучше из-за меньшего объема и колоночной структуры
Show next 13 comments