Чтобы воспользоваться преимуществами оптимизации Dataset
, нужно ли явно использовать методы Dataframe's
(например, df.select(col("name"), col("age")
и т. д.) или вызывать любые методы набора данных — даже RDD- похожие методы (например, filter
, map
и т. д.) также допускают оптимизацию?
Должен ли я явно использовать методы Dataframe, чтобы воспользоваться преимуществами оптимизации набора данных?
Ответы (1)
Оптимизация фрейма данных обычно бывает трех видов:
- Вольфрамовое управление памятью
- Оптимизация запросов Catalyst
- весь кодеген
Управление памятью Tungsten
При определении RDD[myclass] spark не имеет реального представления о том, что такое myclass. Это означает, что в общем случае каждая строка будет содержать экземпляр класса.
Это имеет две проблемы.
Во-первых, это размер объекта. Объект Java имеет накладные расходы. Например, класс case, который содержит два простых целых числа. Выполнение последовательности из 1 000 000 экземпляров и преобразование ее в RDD займет ~26 МБ, а то же самое с набором данных/кадром данных — ~2 МБ.
Кроме того, эта память, когда она выполняется в наборе данных/фрейме данных, не управляется сборкой мусора (она управляется искрой как небезопасная память внутри), и поэтому будет меньше накладных расходов на производительность GC.
Набор данных обладает теми же преимуществами управления памятью, что и кадр данных. Тем не менее, при выполнении операций с наборами данных преобразование данных из внутренней (строковой) структуры данных в класс case приводит к снижению производительности.
Оптимизация запросов Catalyst
При использовании функций фреймов данных spark знает, что вы пытаетесь сделать, и иногда может изменить ваш запрос на эквивалентный, который более эффективен.
Предположим, например, что вы делаете что-то вроде: df.withColumn("a",lit(1)).filter($"b" ‹ ($"a" + 1)).
В основном вы проверяете, если (x ‹ 1 + 1). Spark достаточно умен, чтобы понять это и изменить его на x‹2.
Такого рода операции не могут быть выполнены при использовании операций с наборами данных, поскольку искра не имеет представления о внутренних функциях, которые вы выполняете.
полный кодгенерация
Когда Spark знает, что вы делаете, он может генерировать более эффективный код. В некоторых случаях это может повысить производительность в 10 раз.
Это также невозможно сделать для функций набора данных, поскольку искра не знает внутренностей функций.