Это 21-й день моего участия в Gengwen Challenge, смотрите подробности мероприятия:Обновить вызов
Настройка оператора 1: mapPartitions
Оператор карты нормалей работает с каждым элементом в СДР, а оператор mapPartitions работает с каждым разделом в СДР. Если это обычный оператор карты, предполагая, что раздел имеет 10 000 частей данных, то функция в операторе карты должна выполняться 10 000 раз, то есть оперировать над каждым элементом.
Если это оператор mapPartition, поскольку задача обрабатывает раздел RDD, задача выполнит функцию только один раз, и функция получит все данные раздела одновременно, что более эффективно.
Например, когда вы хотите записать все данные в RDD через JDBC, если вы используете оператор карты, вам нужно создать подключение к базе данных для каждого элемента в RDD, что потребляет много ресурсов. оператор , то для данных одного раздела необходимо установить только одно соединение с базой данных.
У оператора mapPartitions есть и некоторые недостатки: при обычных операциях с картой за один раз обрабатывается одна порция данных, а если памяти не хватает после обработки 2000 порций данных, то 2000 обработанных порций данных могут быть удалены из памяти сборщиком мусора. ; но если вы используете оператор mapPartitions, но когда объем данных очень большой, функция обрабатывает данные одного раздела за один раз.Если памяти недостаточно и память не может быть восстановлена в это время, может произойти OOM, то есть переполнение памяти.
Следовательно, оператор Mappartitions подходит, когда объем данных не особенно велик, а эффект повышения производительности использования оператора Mappartitions по-прежнему хорошо. (Когда объем данных большая, как только оператор Mappartitions используется, он будет напрямую)
В проекте мы должны сначала оценить объем данных RDD, объем данных для каждого раздела и назначенные каждому Исполнителю ресурсы памяти, если позволяют ресурсы, рассмотреть возможность использования операторов mapPartitions вместо карты.
Настройка оператора 2: foreachPartition оптимизирует операции с базой данных
В производственной среде, как правило, операторы foreachPartition для проведения записи в базу данных, характеристики дочернего элемента foreachPartition count, вы можете записать оптимизированную производительность базы данных.
Если вы используете оператор FOREACH для завершения базы данных, поскольку оператор FOREACH используется для перемещения RDD, каждые данные создают соединение с базой данных, что является отличной тратой ресурсов, поэтому для операций базы данных записи мы должны использоваться оператор FORCEACHPARTITION Отказ
Подобно оператору mapPartitions, foreachPartition использует каждую секцию RDD в качестве объекта обхода и обрабатывает данные одной секции за раз. создайте соединение с базой данных один раз, как показано на рисунке ниже:
- После использования оператора foreachPartition можно получить следующие улучшения производительности:
- Для функции function, которую мы написали, обрабатывать данные всего раздела за раз;
- Для данных в разделе создайте уникальное соединение с базой данных;
- В базу данных необходимо отправить только один оператор SQL и несколько наборов параметров;
В производственной среде все операторы будут использовать операции базы данных foreachPartition. Существует проблема оператора foreachPartition и оператора mapPartitions. Точно так же, если объем данных, особенно большой раздел, может вызвать OOM, то есть нехватку памяти.
Настройка трех операторов: перераспределение SparkSQL решает проблему низкой степени параллелизма
В первом разделе общей настройки производительности мы объяснили стратегию настройки параллелизма. Однако настройка параллелизма не действует для Spark SQL. Установленный пользователем параллелизм действителен только для всех этапов Spark, кроме Spark SQL.
Параллелизм Spark SQL не позволяет пользователям указывать самостоятельно, Spark SQL автоматически установит параллелизм этапа, на котором находится Spark SQL, в соответствии с количеством разбиений файлов HDFS, соответствующих таблице куста по умолчанию. параллелизм будет действовать только поэтапно без Spark SQL.
Поскольку параллелизм этапа, на котором находится Spark SQL, не может быть задан вручную, если объем данных большой, а последующие операции преобразования на этом этапе имеют сложную бизнес-логику, то количество задач, автоматически устанавливаемых Spark SQL, очень мало, это означает, что каждая задача обрабатывает большой объем данных, а затем выполняет очень сложную логику обработки, это может проявляться в том, что первый этап со Spark SQL выполняется медленно, а последующие этапы без Spark SQL выполняются очень быстро.
Чтобы решить проблему, что Spark SQL не может задать степень параллелизма и количество задач, мы можем использовать оператор repartition.
Определенно нет возможности изменить степень параллелизма и количество задач на этом шаге Spark SQL, однако для RDD, запрашиваемого Spark SQL, немедленно используйте оператор repartition для переразбиения, чтобы его можно было перераспределить. разделен на несколько разделов, начиная с перераспределения. Для последующих операций RDD, поскольку Spark SQL больше не предназначен, параллелизм этапа будет равен значению, установленному вами вручную, что позволяет избежать того, что этап, на котором находится Spark SQL, может обрабатывать только большой объем данных и выполнять сложные алгоритмы с небольшим количеством логических задач.