Привет знатокам 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 6 more comments
Еще, как минимум нужно учитывать время на чтение из 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()
```

Ну и да, на паркете возможно будет лучше из-за меньшего объема и колоночной структуры
Dmitry Anoshin
один раз в день загрузить и гонять запросы только фильтры меня, получается как куб
Ну мне кажется что если не возиться с установкой кликхаус и конвертировать в json для эластика то по скорости будет редшифт из того что доступно на aws
Al T
Ну мне кажется что если не возиться с установкой кликхаус и конвертировать в json для эластика то по скорости будет редшифт из того что доступно на aws
Плюс там теперь есть materialized views если возможно в вашем случае для скорости покрыть разные кейсы через набор materialized views.
Dmitry Anoshin
один раз в день загрузить и гонять запросы только фильтры меня, получается как куб
А еще вот из области фантастики но по скорости может быть довольно быстро - Aurora mysql with parallel query. Оно будет ваши where на всех нодах параллельно фильтровать.
Show next 8 comments