Я работаю над потоковым проектом Scala (2.11)/Spark (1.6.1) и используя mapWithState()
для отслеживания увиденных данных из предыдущих партий.
Состояние распределено в 20 разделах на нескольких узлах, созданных с помощью StateSpec.function(trackStateFunc _).numPartitions(20)
. В этом состоянии у нас есть только несколько ключей (~ 100), сопоставленных с Sets
с более чем 160 000 записей, которые растут во всем приложении. Все состояние до 3GB
, которое может обрабатываться каждым node в кластере. В каждой партии некоторые данные добавляются в состояние, но не удаляются до самого конца процесса, т.е. ~ 15 минут.
При выполнении пользовательского интерфейса приложения каждое 10-е время обработки партии очень велико по сравнению с другими партиями. Смотрите изображения:
Желтые поля представляют собой большое время обработки.
Более подробное представление Job показывает, что в этих партиях происходит в определенную точку, точно, когда все 20 разделов "пропущены". Или это то, что говорит пользовательский интерфейс.
Мое понимание skipped
заключается в том, что каждый государственный раздел является одной возможной задачей, которая не выполняется, поскольку ее не нужно переучитывать. Однако я не понимаю, почему количество skips
меняется в каждом задании и почему последнее задание требует такой обработки. Чем больше время обработки происходит независимо от размера штата, оно просто влияет на продолжительность.
Является ли это ошибкой в функциональности mapWithState()
или это предполагаемое поведение? Требует ли какая-либо перетасовка базовая структура данных, требуется ли Set
в состоянии копировать данные? Или это скорее будет недостатком в моем приложении?