为什么我需要将广播用于与已广播的rdd的共享变量?

时间:2019-05-13 12:15:54

标签: apache-spark broadcast

enter image description here taskBinary = sc.broadcast(taskBinaryBytes)中有代码DAGScheduler's submitMissingTasks(....),带有func的RDD已被广播。

然后ShuffleMapTask和ResultTask将反序列化taskBinary以在Executor上运行。因此,sparkaleardy帮助我们在广播任务时将共享变量发送给执行程序。

为什么我需要自己使用sc.broadcast(xxxxxx)

我已经弄清楚了。我以前不知道反序列化机制。尽管Spark aleardy广播了RDD和共享变量,但是如果在反序列化任务将获得不同的共享var时不使用广播(多次反序列化,任务反序列化不能无效),则会花费更多的时间和更多的内存。

在我们的代码中,广播仅有助于减少反序列化阶段的时间和内存,而无助于任务序列化并复制到执行者阶段。

1 个答案:

答案 0 :(得分:0)

因为如果您仅使用局部变量,即$(document).ready( function(){ var buttonFilter; var suche = $('.filter_search'); var qsRegex; var price = 0; var filters = []; $(".grid").addClass("show-me"); filters.push(".show-me"); var $grid = $('.grid').isotope({ itemSelector: '.item', percentPosition: true, getSortData: { sortname: '.sort-name', sortprice: '.sort-price', number: '.sort-price parseInt' }, filter: function(){ var searchResult = qsRegex ? $(this).text().match(qsRegex) : true; var buttonResult = buttonFilter ? $(this).is(buttonFilter) : true; return searchResult && buttonResult; } }); $('.filters-select').on('change', function(){ var sortValue = $(this).find(':selected').data('sort-value'); var direction = $(this).find(':selected').data('sort-direction'); var isAscending = (direction == 'asc'); $grid.isotope({ sortBy: sortValue, sortAscending: isAscending }); }); $('#noFilterResult').hide(); var quicksearch = suche.keyup(debounce(function(){ qsRegex = new RegExp(quicksearch.val(), 'gi'); $grid.isotope(); if(!$grid.data('isotope').filteredItems.length){ $('#noFilterResult').show(); }else{ $('#noFilterResult').hide(); } },200)); function debounce(fn, threshold){ var timeout; return function debounced(){ if(timeout){ clearTimeout(timeout); } function delayed(){ fn(); timeout = null; } timeout = setTimeout(delayed, threshold || 100); }; } $("#range").ionRangeSlider({ hide_min_max: true, keyboard: true, min: 0, max: 999, from: 0, to: 999, type: 'double', step: 1, prefix: "", grid: false, onChange: function(data){ $(".item").each(function(){ price = parseInt($(this).find(".sort-price").text(), 10); if(data.from <= price && data.to >= price){ $(this).addClass('show-me'); }else{ $(this).removeClass('show-me'); } }); $grid.isotope({ itemSelector: '.item', filter: '.show-me' }); } }); }); ,Spark会将其打包并与您的代码一起发送给每个任务!

在广播的情况下,val data = list(1, 4, 5)将被复制到每个执行器上,因此可以在本地使用。

在某些情况下,您可能有大数据量,并且想要避免序列化每个任务的数据,而是可以使用val broadcastData = sc.broadcast(data)将其发送给每个执行程序,然后任务可以在本地访问数据。

更新:

正如@Fish所提到的,Spark似乎内部使用广播来分发任务数据,这可以在此处的方法broadcast中看到:

https://github.com/apache/spark/blob/master/core/src/main/scala/org/apache/spark/scheduler/DAGScheduler.scala

尽管任务的序列化大小不应超过submitMissingTasks确定的1MB。