Цель foo — просто инкапсулировать временные переменные (DataFrames), которые я не хочу иметь во внешней области. base — это сложный DF, используемый дважды, поэтому я кэширую его. Мои вопросы касаются явного вызова count (предложенного ChatGPT). Это необходимо для запуска кэширования, но мне кажется, что это неправильный дизайн.
Зачем нам нужен счетчик (действие) на данном этапе? В чем выгода? Фактическое кэширование в любом случае произойдет при первом действии по отношению к возвращаемому значению foo, если бы я не вызвал count.
Я заметил, что вызов foo code> дважды с одним и тем же вводом df имеет разное время выполнения: первое — медленное, что и ожидалось, поскольку вызывается счетчик. А вот второй почти мгновенный. Почему это? Конечно, base уже кэширован, а затем count тривиален, но ссылка на base во втором запуске — это другая ссылка, чем ссылка при первом запуске. Откуда Spark узнает, что он может повторно использовать кэшированный DF с первого запуска? (чья память, кстати, я слил, я думаю, так как после выхода foo я не могу ее отменить.)
Действительно ли у нас есть утечка памяти при выходе foo ? Как я могу отменить сохранение базы? Должен ли я вообще отказаться от настойчивости? Я знаю, что существует spark.catalog.clearCache() для уничтожения всех кэшированных DF, но я хотел бы сделать это явно для базы. Вот почему в функции есть/было предложение Final, чтобы предотвратить утечку, но это была неудачная попытка, поскольку в этом случае я освобождал кеш еще до того, как смог его использовать...
У меня есть игрушка-пример функции, возвращающая кэшированный искровой DataFrame (DF): [code]def foo(df): try: base = complicated_query(df) base.cache() # lazy cache base.count() # trigger cache - wrong design??? num1 = base.withColumn('number', f.lit('1')) num2 = base.withColumn('number', f.lit('2')) return num1.union(num2) finally: None # base.unpersist() [/code] Цель foo — просто инкапсулировать временные переменные (DataFrames), которые я не хочу иметь во внешней области. base — это сложный DF, используемый дважды, поэтому я кэширую его. Мои вопросы касаются явного вызова count (предложенного ChatGPT). Это необходимо для запуска кэширования, но мне кажется, что это неправильный дизайн. [list] [*]Зачем нам нужен счетчик (действие) на данном этапе? В чем выгода? Фактическое кэширование в любом случае произойдет при первом действии по отношению к возвращаемому значению foo, если бы я не вызвал count. [*]Я заметил, что вызов foo code> дважды с одним и тем же вводом df имеет разное время выполнения: первое — медленное, что и ожидалось, поскольку вызывается счетчик. А вот второй почти мгновенный. Почему это? Конечно, base уже кэширован, а затем count тривиален, но ссылка на base во втором запуске — это другая ссылка, чем ссылка при первом запуске. Откуда Spark узнает, что он может повторно использовать кэшированный DF с первого запуска? (чья память, кстати, я слил, я думаю, так как после выхода foo я не могу ее отменить.) Действительно ли у нас есть утечка памяти при выходе foo ? Как я могу отменить сохранение базы? Должен ли я вообще отказаться от настойчивости? Я знаю, что существует spark.catalog.clearCache() для уничтожения всех кэшированных DF, но я хотел бы сделать это явно для базы. Вот почему в функции есть/было предложение Final, чтобы предотвратить утечку, но это была неудачная попытка, поскольку в этом случае я освобождал кеш еще до того, как смог его использовать... [/list] Можете ли вы помочь решить эту проблему?