Эта статья приняла участие в мероприятии «Церемония создания новичков», чтобы вместе начать путь создания золота.
Сегодня я познакомлю вас с моделью памяти Spark.Там много галантереи, не пропустите~
с частым размещением данныхMapreduce
Двигатель другой, Спарк основан на内存
Распределенный вычислительный движок со встроенным мощным механизмом управления памятью для обеспечения优先内存
обработки и поддерживает хранение данных на диске.
В этой статье основное внимание будет уделено тому, как реализовано управление памятью Spark, а именно:
- Обзор искровой памяти
- Механизм управления памятью Spark
- Выделение памяти в режиме Spark on Yarn
1 Обзор памяти Spark
Во-первых, краткое введение в основной процесс запуска Spark.
- пользователь в
Driver
Клиент отправляет задачу и инициализирует рабочую среду (SparkContext и т. д.). - Драйвер в соответствии с конфигурацией
ResoureManager
Подать заявку на ресурсы (исполнители и ресурсы памяти) - Менеджер ресурсов ResoureManager выбирает соответствующий
worker
Node создает процесс-исполнитель -
Executor
Зарегистрируйтесь у Водителя и дождитесь его назначенияtask
Задача - Водительская сторона завершена
SparkContext
Инициализируйте, создайте DAG, назначьте набор задач Executor для выполнения. - Исполнитель запускает поток для выполнения задачи задачи и возвращает результат.
Spark запустится при выполнении задачиDriver
иExecutor
два процесса. Помимо того, что он служит узлом выполнения для задач отправки Spark, процесс Driver также отвечает за подачу заявок на ресурсы Executor, регистрацию Executors и отправку задач для завершения координации и планирования всей задачи. Процесс Executor отвечает за выполнение определенных задач на рабочих узлах.task
задачу и поддерживать связь с драйвером, чтобы вернуть результат.
Как видно из вышеизложенного, расчет данных Spark происходит в основном вExecutor
Завершение в процессе и исполнитель для RDD持久化
хранение иShuffle
Запущенный процесс осуществляется единообразно в рамках механизма управления памятью Spark, и запущенные в нем задачи также共享
Память Executor, поэтому в этой статье в основном описывается управление памятью Executor.
Искровая память делится на堆内内存
(память в куче) и堆外内存
(память вне кучи). где память в куче основана наJVM内存
модель, в то время как доступ к памяти вне кучи осуществляется путем вызова базовойJDK Unsafe API
. Два типа памяти объединены интерфейсом модуля управления памятью Spark.
def acquireStorageMemory(...): Boolean //申请存储内存
def acquireExecutionMemory(...): Long //申请执行内存
def releaseStorageMemory(...): Unit //释放执行内存
def releaseStorageMemory(...): Unit //释放存储内存
1.1 Память в куче Spark
Исполнитель какJVM
Процесс, внутреннее устройство которого основано на модели управления памятью JVM.
Spark инкапсулирует унифицированный интерфейс управления памятью поверх него.MemoryManager
, за счет разумного планирования (логического) пространства кучи JVM заполнить пространство памяти экземпляра объекта申请
и释放
. Убедитесь, что пространство памяти максимально увеличено в соответствии с операционным механизмом Spark.
участие здесь
JVM堆
Понятие пространства, простое описание есть в программе, о экземпляре объекта | массиве创建
,使用
и释放
Вся память управляется и распределяется в области памяти, называемой «кучей JVM» в JVM.
После того, как программа Spark создаст объект, JVM сохранит его в куче памяти.
分配
определенный размер пространства, создатьClass对象
И возвращает ссылку на объект, Spark сохраняет ссылку на объект и записывает информацию о занятой памяти.
Параметры памяти в куче в Spark:-executor-memory
или-spark-executor-memory
. Обычно он определяется в параметрах при отправке задачи и совпадает с-executor-cores
и другие связанные конфигурации передаются в ResourceManager для приложения ресурсов Executor.
Создайте определенное количество Executors на рабочем узле, и каждый Executor будет выделен
-executor-memory
размер оперативной памяти. Память в куче Executor совместно используется всеми задачами потока задач, и несколько потоков обмениваются данными в памяти.
Память кучи Spark в основном делится наStorage
(память для хранения),Execution
(исполнительная память) иOther
(Другое) несколько частей.
- Использование памяти для кэширования данных RDD и широковещательных переменных
- Выполнение обеспечивает только использование памяти для процесса перемешивания
- Другое предоставляет место в памяти для внутренних объектов Spark и пользовательских объектов.
Spark поддерживает различные режимы управления памятью.В разных режимах управления доля вышеперечисленных разделов памяти в куче будет разной.Конкретные подробности будут описаны в главе 2.
1.2 Память Spark вне кучи
Spark1.6
На основе памяти в куче вводится память вне кучи для дальнейшей оптимизации использования памяти Spark.
На самом деле, если у вас есть опыт программирования, связанный с Java, я думаю, вам не привыкать к использованию памяти вне кучи. его основной вызов
基于C
Метод класса JDK Unsafe через指针
Непосредственно выполнять операции с памятью, включая применение, использование, удаление и освобождение памяти.
Spark отказался от предыдущей версии после 2.xTachyon
, используя общий Java на основеJDK Unsafe API
для управления памятью вне кучи. Этот режим не применяется к памяти в JVM, а напрямую управляет памятью операционной системы, уменьшая объем памяти в JVM.空间切换
стоимость, уменьшаяGC回收
Занято потребление, чтобы добиться точного контроля памяти.
Память вне кучи не включена по умолчанию, вам нужно установить ее в конфигурацииspark.memory.offHeap.enabled
Установите значение True и настройтеspark.memory.offHeap.size
Параметр задает размер кучи.
Для разделения памяти вне кучи она включает только две области: Execution (память выполнения) и Storage (память для хранения), которые совместно используются всеми задачами потока задач.
2 Механизм управления памятью Spark
Как было сказано выше, соотношение областей памяти Spark in-heap и out-of-heap в разных режимах разное.
До Spark 1.6 Spark использовал静态管理
(Менеджер статической памяти), соотношение распределения памяти выполнения и памяти хранения静态
, значение которого является заданным системой параметром по умолчанию.
После Spark 1.6, чтобы учесть динамическую гибкость управления памятью, управление памятью Spark было изменено на统一管理
(Unified Memory Manager), поддерживает память для хранения и выполнения动态占用
. Поскольку статический метод управления все еще зарезервирован, вы можете пройтиspark.memory.useLegacyMode
параметр включен.
2.1 Менеджер статической памяти
Spark — это самый примитивный режим управления памятью.По умолчанию параметры конфигурации памяти, установленные системой, используются для выделения соответствующего пространства памяти, такого как Storage и Execution, и поддерживают пользовательскую модификацию конфигурации.
1. Выделение памяти в куче
Пространство кучи памяти в целом разделено наStorage
(память для хранения),Execution
(исполнительная память),Other
(Другая память) три части, по умолчанию в соответствии с6:2:2
отношение деления. Среди них параметры области памяти Storage:spark.storage.memoryFraction
(по умолчанию 0,6), параметры области исполнительной памяти:spark.shuffle.memoryFraction
(по умолчанию 0,2). Другая область памяти в основном используется для хранения определяемых пользователем структур данных и внутренних метаданных Spark, что составляет 20% системной памяти.
В области Storage memory 10% от размера используется какReserved
Зарезервировать место для предотвращения переполнения памяти по параметрам:spark.shuffle.safetyFraction
(по умолчанию 0,1) Управление. 90% пространства используется как доступная память для хранения.Вот область памяти, где Executor кэширует данные RDD и широковещательные данные.Параметры такие же, как Reserved. другая частьUnroll
Область, в которой в основном хранятся данные процесса развертывания, занимает 20% доступного места для хранения.
Процесс развертывания:
Прежде чем RDD будет кэширован в памяти,partition
Экземпляр объекта записи в другой области памяти в куче不连续
хранится в космосе. В процессе кэширования RDD разделы в дискретном пространстве хранения преобразуются в连续存储空间
Объект Block хранится в области памяти Storage, этот процесс называется Unroll.
В области Execution memory 20% размера используется как зарезервированное зарезервированное пространство для предотвращения OOM и других ситуаций, когда памяти не хватает, по параметрам:spark.shuffle.safetyFraction
(по умолчанию 0,2) Контроль. 80% пространства используется как доступная память выполнения для кэширования промежуточных данных процесса тасования.Параметры:spark.shuffle.safetyFraction
(по умолчанию 0,8).
Формула расчета
可用的存储内存 =
systemMaxMemory
* spark.storage.memoryFraction
* spark.storage.safetyFraction
可用的执行内存 =
systemMaxMemory
* spark.shuffle.memoryFraction
* spark.shuffle.safetyFraction
2. Память вне кучи
По сравнению с памятью в куче выделение памяти вне кучи проще. Память вне кучи по умолчанию384M
, по системному параметруspark.yarn.executor.memoryOverhead
настраивать. Общая память делится на две части: Storage и Execution.Распределение этой части соответствует памяти в куче.Параметры:spark.memory.storageFaction
Принять решение. В памяти вне кучи обычно хранятся сериализованные двоичные данные (поток байтов), которые представляют собой непрерывную область памяти в пространстве для хранения, и ее размер можно точно рассчитать, поэтому в настоящее время нет необходимости устанавливать зарезервированное пространство.
3. Резюме
- Механизм реализации прост и понятен
- Склонна к возникновению проблема дисбаланса памяти, то есть на одной стороне Storage and Execution имеется избыточная память, а на другой — недостаточное содержимое.
- От разработчиков требуется полное понимание механизма хранения, а настройка неудобна
Для более подробных обсуждений добро пожаловать в мой личный WeChat:youlong525
2.2 Единый диспетчер памяти
Чтобы решить (Менеджер статической памяти) управление статической памятью内存失衡
д., Spark использует новый режим управления памятью после 1.6 — Unified Memory Manager (Унифицированный диспетчер памяти). В новом режиме убрано и включено статическое выделение памяти Executor в старом режиме内存动态占比机制
и разделить Storage и Execution на единую общую область памяти.
1. Память в куче
Куча памяти делится в целом наUsable Memory
(доступная память) иReversed Memory
(зарезервированная память) две части. Зарезервированная память используется в качестве области использования памяти для нештатных ситуаций, таких как OOM, и по умолчанию выделяется 300 МБ. Доступная память может быть дополнительно разделена на объединенную память (Единая память) и две другие части Прочей памяти, соотношение по умолчанию — 6:4.
Storage (память хранения), Execution (память выполнения) и Other memory в объединенной памяти имеют те же параметры и область применения, что и режим статической памяти, и здесь повторяться не будут. В настоящее время он включен только между Storage и Execution.动态内存占用
механизм.
Механизм динамического заполнения памяти
- Установите начальное значение памяти, то есть и Исполнение, и Хранилище должны установить свои диапазоны областей памяти (параметр по умолчанию 0,5)
- Если на одной стороне недостаточно памяти, а на другой стороне есть свободная память, она может занять пространство памяти другой стороны.
- Когда памяти обеих сторон недостаточно, диск нужно поставить на обработку.
- Когда исполнительная память занята, Storage необходимо сбросить эту часть на жесткий диск и вернуть место
- Когда память Storage занята, Execution не нужно возвращать
2. Память вне кучи
В соответствии с распределением в режиме статического управления значение по умолчанию для памяти вне кучи составляет 384 МБ. Целое разделено на две части, Storage и Execution, и включено动态内存占用
механизм, в котором коэффициент инициализации по умолчанию равен 0,5.
Формула расчета
// 可用的存储&执行内存 =
(systemMaxMemory -ReservedMemory)
* spark.memoryFraction
* spark.storage.storageFraction
// (启用内存动态分配机制,己方内存不足时可占用对方)
3. Резюме
- Динамическое соотношение памяти для улучшения разумного использования памяти
- Унифицированное управление памятью для хранения и выполнения для легкой настройки и обслуживания
- Поскольку выполнение занимает память Storage, планировать его не нужно, и возникает ситуация, когда память Storage недостаточно часто проверяется GCed.
3 Распределение памяти в режиме Spark On Yarn
Благодаря надежному механизму управления памятью Spark Executor может эффективно обрабатывать операции с памятью и потоки данных RDD в узлах. Yarn, как менеджер ресурсов для выделения памяти Executor, как обеспечить наиболее рациональное выделение памяти в процессе — тоже проблема, достойная внимания.
Сначала посмотрите на основной процесс Spark On Yarn:
-
- Spark
Driver
Отправьте программу и подайте заявку на Yarn for Application
- Spark
-
- Yarn принимает ответ на запрос и создает AppMaster на узле NodeManager.
-
-
AppMaster
Подать заявку на ресурсы (контейнер) из Yarn ResourceManager
-
-
- Выберите соответствующий узел для создания
Container
(исполнительный процесс)
- Выберите соответствующий узел для создания
-
- Последующие водители начинают планировать и запускать задачи
Режимы Yarn Client и Yarn Cluster различаются в некоторых аспектах, но основные процессы схожи. Конфигурация памяти, задействованная во всем процессе, следующая (конфигурация исходного кода по умолчанию):
var executorMemory = 1024
val MEMORY_OVERHEAD_FACTOR = 0.10
val MEMORY_OVERHEAD_MIN = 384
// Executo堆外内存
val executorMemoryOverhead =
sparkConf.getInt("spark.yarn.executor
.memoryOverhead",
math.max((MEMORY_OVERHEAD_FACTOR
* executorMemory).toInt
, MEMORY_OVERHEAD_MIN))
// Executor总分配内存
val executorMem= args.executorMemory
+ executorMemoryOverhead
Итак, предположим, что когда мы отправляем искровую программу, если мы устанавливаем-executor-memory
=5г.
spark-submit
--master yarn-cluster
--name test
--executor-memory 5g
--driver-memory 5g
По формуле расчета в исходном коде мы можем получить:
memoryMem= args.executorMemory(5120) + executorMemoryOverhead(512) = 5632M
Однако на самом делеYarn UI
Память не это значение? Это связано с тем, что Yarn включен по умолчанию.资源规整化
.
1. Регулировка ресурсов пряжи
Yarn всесторонне оценивает количество ресурсов, запрошенных в настоящее время, в соответствии с минимальным количеством ресурсов, которые могут быть применены, максимальным количеством ресурсов, которые могут быть применены, и коэффициентом нормализации, чтобы рационально нормализовать ресурсы приложения.
- определение
Если запрашиваемый программой ресурс не является целым кратным этому фактору, он будет изменен на значение, соответствующее наименьшему целому кратному
公式: ceil(a/b)*b
(a是程序申请资源,b为规整化因子)
- Связанная конфигурация
yarn.scheduler.minimum-allocation-mb:
最小可申请内存量,默认是1024
yarn.scheduler.minimum-allocation-vcores:
最小可申请CPU数,默认是1
yarn.scheduler.maximum-allocation-mb:
最大可申请内存量,默认是8096
yarn.scheduler.maximum-allocation-vcores:
最大可申请CPU数,默认是4
Вернемся к предыдущему расчету памяти: поскольку вычисленное значение memoryMem равно5632
, не является целым числом, кратным коэффициенту нормализации (1024), поэтому его необходимо пересчитать:
memoryMem = ceil(5632/1024)*1024=6144M
2. Разница в распределении памяти драйвера в режиме Yarn
Yarn Client и Cluster отправляются двумя способами, и выделение памяти Executor и Driver также отличается. Все ApplicationMasters в Yarn позволяютContainer
бежать;
По умолчанию Контейнер в клиентском режиме имеет1G
Память, 1 ядро процессора, конфигурация режима кластера задаетсяdriver-memory
иdriver-cpu
Чтобы указать, то есть драйвер в режиме клиента является значением памяти по умолчанию, драйвер в режиме кластера является пользовательской конфигурацией.
- Кластерный режим (память драйвера: 5g): ceil(a/b)*b может получить память драйвера 6144M
- клиентский режим (память драйвера: 5g): ceil(a/b)*b может получить память драйвера 5120M
3. Резюме
В качестве диспетчера распределенных ресурсов Apache Yarn имеет собственный механизм оптимизации управления памятью. При развертывании программ Spark в Yarn вам необходимо учитывать механизмы обработки памяти обоих, что является одним из наиболее часто упускаемых из виду знаний в производственных приложениях.
напиши в конце
Механизм управления памятью Spark является ключевым содержанием принципа и настройки Spark.Эта статья начинается с двух режимов, Static Memory Manager (статический режим управления) и Unified Memory Manager (унифицированный режим управления), и простыми словами объясняет, как работает вычислительная модель Spark. управление памятью.В конце описывается выделение памяти в Spark On Yarn.Надеюсь вышеизложенное может вам помочь.
》》》Чтобы получить больше хороших статей, пожалуйста, обратите внимание на мой публичный аккаунт: Big Data Arsenal