Локальность данных в 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 уровня локальности:

Задачи назначаются по-порядку от наивысшего уровня к низшему. Но это еще не все, планировщик должен учитывать и загруженность каждого узла. К примеру, данные расположены на узле A, в то время как Spark работает на узлах A, B, C. Если опираться только на местоположение, то все задачи будут выполняться на узле A. Это приведет к неравномерной нагрузке, а часть кластера будет вообще простаивать.

Для управления, через сколько секунд данные будут помечены более низким уровнем, а значит переданы на другие узлы, отвечает настройка spark.locality.wait. Такая же настройка есть отдельно для каждого уровня.

Вывод

Зная как работает локальность данных в Spark и тем как ей управлять, можно ускорить процесс обработки данных. Хотя в сети, часто советуют устанавливать spark.locality.wait в 0, делать можно лишь тогда, когда вы уверены в своей инфраструктуре.