Сценарий:
Кафка -> Spark Streaming
Logi c в каждой микропакете Spark Streaming (30 секунд):
Чтение Json -> Разбор Json -> Отправить по Kafka
Моя потоковая работа читает около 1007 *1000* 1008 * тем Kafka, с 10K разделами Kafka, пропускная способность была около 5 миллионов событий / с .
Проблема возникает из-за неравномерной загрузки c между разделами Kafka, некоторые разделы имеют пропускную способность примерно в 50 раз меньшую, что приводит к перекосу разделов RDD (поскольку KafkaUtils создает отображение 1: 1 из Kafka разделы на разделы Spark) и действительно ухудшают общую производительность, потому что для каждой микропакета большинство исполнителей ждут того, который имеет наибольшую нагрузку до конечной sh, я знаю это, глядя на Spark UI, в некоторой точке каждой микропакета, только несколько исполнителей имеют «АКТИВНЫЕ» задачи, все остальные исполнители выполняют свою задачу и ожидают, также, просматривая распределение времени задачи, MAX составляет 2,5 минута, но MEDIAN составляет всего 20 секунд.
Примечания:
- Потоковая передача Spark не структурированная
- Мне известен этот пост Spark - repartition () vs coalesce () , я не спрашиваю о разнице между repartition () или coalesce (), нагрузка постоянна, поэтому не имеет отношения к автоматическому масштабированию или динамическому c распределению также
Что Я пытался:
- Coalesce () немного помогает, но не устраняет асимметрию, а иногда даже хуже, также имеет более высокий риск для OOM для исполнителей.
- Repartition () удаляет асимметрию, но полная перетасовка просто слишком дорога в этом масштабе, штраф не окупается за время выполнения для каждой партии, увеличение времени партии не работает также потому, что, когда время партии увеличивается, нагрузка увеличивается для каждой микропакета, а рабочая нагрузка увеличивается. shuffle также увеличивается
Как сделать рабочую нагрузку более равномерно распределенной между исполнителями Spark, чтобы ресурсы использовались более повторно эффективно? И производительность будет лучше?