В пользовательской функции комбинирования лучей выполняется сериализация, даже если объект находится на той же машине?

У нас есть пользовательская функция объединения (в beam sdk 2.0), в которой миллионы объектов накапливаются, но они НЕ обязательно уменьшаются... то есть они иногда добавляются в список, так что в конечном итоге список может стать довольно большие (сотни мегабайт, даже гигабайты).

Чтобы свести к минимуму проблему «обхода» этих объектов (во время слияния аккумуляторов) между узлами, мы создали ОДИН гигантский узел (64 ядра, тонны оперативной памяти).

Таким образом, в «теоретике» потоку данных не нужно сериализовать объект списка (и любой из этих больших объектов в списке) даже во время операций «аккумулятора слияния», поскольку все объекты находятся на одном узле. Но сериализуется ли поток данных по-прежнему, даже если все интересующие объекты находятся на одном узле, или он достаточно умен, чтобы знать, что объект находится на одном узле, а не на разных узлах?

В идеале, когда объекты находятся на одном узле, мы можем просто передавать ссылки на объекты (вместо сериализации/десериализации содержимого этих объектов, которые могут быть очень и очень большими). Конечно, чем при работе с несколькими узлами, нет другого выбора, кроме как сериализовать/десериализовать, поскольку данные должны каким-то образом передаваться; но внутри узла луч SDK 2.0 достаточно умен, чтобы не сериализовать/десериализовать во время этих функций объединения, группировать по так далее.?)


person Jonathan Sylvester    schedule 28.06.2017    source источник


Ответы (1)


Служба потока данных агрессивно оптимизирует ваш конвейер, чтобы избежать ненужной сериализации. Вас интересует оптимизация fusion, описано здесь, в документации по потоку данных. Когда данные проходят через объединенную «стадию» (последовательность низкоуровневых инструкций, примерно соответствующих шагам во входном конвейере), они не сериализуются и не десериализуются.

Однако, если ваш CombineFn создает список, и этот список становится большим, вы должны попытаться перефразировать свой конвейер, чтобы использовать необработанный GroupByKey. Еще одна важная оптимизация — «подъем объединителя» или «объединение на стороне сопоставления», когда CombineFn применяется для каждого ключа локально перед перетасовкой данных между машинами, исходя из предположения, что накопитель будет меньше, чем просто список элементов. Таким образом, весь список будет сериализован, перемешан и десериализован до завершения преобразования Combine. Если вместо этого вы используете GroupByKey напрямую, ваши элементы будут передаваться намного эффективнее без сериализации всего списка.

Я должен отметить, что другие бегуны Beam также выполняют стандартную оптимизацию слияния и другие. Все они обычно берутся из работы по функциональному программированию в конце 80-х — начале 90-х годов и применялся для распределенной обработки данных в FlumeJava, примерно в 2010 г., так что это базовое ожидание сейчас.

person Kenn Knowles    schedule 28.06.2017