Я изучаю Spark и пытаюсь обработать огромный набор данных. Я не понимаю, почему я не вижу уменьшения времени завершения этапа со следующей стратегией (псевдо):

data = sc.textFile(dataset).cache()

while True:
    data.count()
    y = data.map(...).reduce(...)
    data = data.filter(lambda x: x < y).persist()

Идея состоит в том, чтобы выбрать y так, чтобы в большинстве случаев данные уменьшались вдвое. Но почему-то кажется, что все данные всегда снова обрабатываются на каждом count ().

Это какой-то антипаттерн? Как мне это сделать со Spark?

0
ggggr 15 Ноя 2019 в 21:19

2 ответа

Да, это антипаттерн.

map, как и большинство, но не все, распределенные примитивы в Spark, в значительной степени по определению является подходом "разделяй и властвуй". Вы берете данные, вычисляете разбиения и прозрачно распределяете вычисления отдельных разбиений по кластеру.

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

0
user12380127 15 Ноя 2019 в 21:40

Spark вычисляется лениво, поэтому в цикле for или while перед каждым вызовом data.filter не возвращаются последовательно данные, а вместо этого последовательно возвращаются вызовы Spark, которые будут выполнены позже. Все эти вызовы агрегируются и затем выполняются одновременно, когда вы делаете что-то позже.

В частности, результаты остаются неоцененными и просто представлены до тех пор, пока не будет вызвано действие Spark. После определенного момента приложение не может справиться с таким количеством параллельных задач.

В некотором смысле мы сталкиваемся с конфликтом между двумя разными представлениями: conventional structured coding with its implicit (or at least implied) execution patterns and independent, distributed, lazily-evaluated Spark representations.

0
ashwin agrawal 15 Ноя 2019 в 22:57
Однако есть призыв к сохранению после filter () ... Должен ли он вычислить его немедленно? Это итеративный алгоритм, поэтому мне интересно, как я должен его программировать, поскольку мне нужен результат предыдущего расчета, чтобы перейти к следующему этапу.
 – 
ggggr
16 Ноя 2019 в 21:56
Чтобы избежать антипаттерна, вы можете выполнять вычисления на лету, что сэкономит время сохранения, это один из подходов, я могу предложить вам несколько других подходов, если вы можете поделиться точными данными и проблемой.
 – 
ashwin agrawal
16 Ноя 2019 в 23:10
Примите ответ, если он устранил проблему.
 – 
ashwin agrawal
25 Ноя 2019 в 00:48