Локальность данных в Spark
В обработке больших данных принято доставлять не данные к обработчику, а на оборот - обработчик к данным, но это не всегда возможно. Поэтому важную роль играет локальность данных (Data Locality). При работе со Spark, в интерфейсе, можно видеть колонки со значениями NODE_LOCAL, ANY или PROCESS_LOCAL - это и есть показатель локальности данных.
Предпочтительное местоположение
Каждое приложение Spark имеет важный класс, называемый DAGScheduler. DAGScheduler расшифровывается как Direct Acyclic Graph Scheduler и является ядром выполнения любой задачи в кластере Spark. Это класс фактически берет задачи и отправляет их исполнителям для обработки.
Одной из первых операций, которую выполняет DAGScheduler, перед тем как передать задачу на выполнение, является чтение заголовков из RDD. Где помимо прочего, проверяется значение preferredLocation
- информация о местонахождении данных.
А в исходном коде RDD, функция возвращающая эти данные помечена как Optionally overridden by subclasses to specify placement preferences
. Из этого можно сделать важный вывод: что решение о том, что является «локальным», будет основываться исключительно на том, что разработчик RDD решил сделать «локальным» и имеет ли планировщик доступ к нужным данным.
Уровни локальности
Существует 4 уровня локальности:
- PROCESS_LOCAL - This task will be run within the same process as the source data
- NODE_LOCAL - This task will be run on the same machine as the source data
- RACK_LOCAL – This task will be run in the same rack as the source data
- ANY (NO_PREF) - This task cannot be run on the same process as the source data or it doesn’t matter
Задачи назначаются по-порядку от наивысшего уровня к низшему. Но это еще не все, планировщик должен учитывать и загруженность каждого узла. К примеру, данные расположены на узле A, в то время как Spark работает на узлах A, B, C. Если опираться только на местоположение, то все задачи будут выполняться на узле A. Это приведет к неравномерной нагрузке, а часть кластера будет вообще простаивать.
Для управления, через сколько секунд данные будут помечены более низким уровнем, а значит переданы на другие узлы, отвечает настройка spark.locality.wait
. Такая же настройка есть отдельно для каждого уровня.
Вывод
Зная как работает локальность данных в Spark и тем как ей управлять, можно ускорить процесс обработки данных. Хотя в сети, часто советуют устанавливать spark.locality.wait
в 0, делать можно лишь тогда, когда вы уверены в своей инфраструктуре.