У меня есть много данных, которые я пытаюсь извлечь кусками - скажем, 3 куска - и не кэшировать все сразу в памяти. Однако я бы хотел сохранить его (действие) одновременно и впоследствии.

Это текущая упрощенная стратегия:

for query in [query1,query2,query3]:

    df = spark.sql(query)

    df.cache()

    df1 = df.filter('a')
    df2 = df.filter('b')

    final_output_1 = final_output_1.join(df1)
    final_output_2 = final_output_2.join(df2)

    df.unpersist()


final_output_1.write.saveAsTable()
final_output_2.write.saveAsTable()

Итак, первый вопрос: unpersist() здесь не сработает, поскольку на df еще не было никаких действий?

второй вопрос: как здесь работает df.cache(), когда я повторно использую переменную df в цикле for? Я знаю, что он неизменен, поэтому он сделает копию, но действительно ли unpersist() очистит эту память?

0
hunterm 13 Фев 2021 в 02:27

1 ответ

Лучший ответ

Кэширование используется в Spark, когда вы хотите повторно использовать фрейм данных снова и снова,

Например: таблицы сопоставления

Как только вы кешируете ff, вам нужна операция действия для физического перемещения данных в память, поскольку искра основана на ленивом выполнении.

В твоем случае

df.cache()

Не будет работать должным образом, поскольку после этого вы не выполняете никаких действий.

Чтобы кеш работал, вам необходимо запустить df.count () или df.show () или любое другое действие для перемещения данных в память, иначе ваши данные не будут перенеситесь в память, и вы не получите никакого преимущества. и поэтому df.unpersist () также избыточен.

Первый вопрос:

Нет, ваши df.cache () и df.unpersist () не будут работать, поскольку изначально не было кэшированных данных, поэтому их нечего терять.

Второй вопрос:

Да, вы можете использовать то же имя переменной, и если действие будет выполнено, данные будут кэшироваться, и после ваших операций df.unpersist () будет удалять данные в каждом цикле. Таким образом, предыдущий DF не имеет связи со следующим DF в следующем цикле. Как вы сказали, они неизменяемы , и поскольку вы назначаете новый запрос той же переменной в каждом цикле, он действует как новый DF (не связанный с предыдущим DF).

Основываясь на вашем коде, я не думаю, что вам нужно делать кеширование, поскольку вы выполняете только одну операцию.

См. Когда кэшировать DataFrame? и Если я кэширую фрейм данных Spark, а затем перезаписываю ссылку, будет исходный фрейм данных все еще кэшируется?

1
Andy_101 13 Фев 2021 в 08:12