在哪种情况下,来自驱动程序节点的对象被序列化并发送到 apache spark 中的工作节点

Posted

技术标签:

【中文标题】在哪种情况下,来自驱动程序节点的对象被序列化并发送到 apache spark 中的工作节点【英文标题】:In which scenario Object from driver node is serialized and sent to workers node in apache spark 【发布时间】:2019-02-04 18:17:00 【问题描述】:

假设我声明了一个变量,并在 spark 的 map/filter 函数中使用它。对于map/filter的值的每个操作,我上面声明的变量是否每次都从驱动程序发送到工作人员。

我的 helloVariable 是否会针对 consumerRecords 的每个值发送到工作节点?如果可以,如何避免?

String helloVariable = "hello testing"; //or some config/json object
JavaDStream<String> javaDStream = consumerRecordJavaInputDStream.map(
    consumerRecord -> 
     return consumerRecord.value()+" --- "+helloVariable;
     );

【问题讨论】:

【参考方案1】:

是的。当您通常将函数传递给 Spark 时,例如 map() 或 filter(),这些函数可以使用在驱动程序中定义在它们之外的变量,但是在集群上运行的每个任务都会获得每个变量的新副本(使用序列化并通过网络发送),并且来自这些副本的更新不会传播回驱动程序。 所以这种场景的常见情况是使用广播变量。 广播变量允许程序员在每台机器上缓存一个只读变量,而不是随任务一起发送它的副本。如果您对广播机制感兴趣,here 可以阅读非常好的简短说明。 根据 Spark 文档,这个过程可以像这样以图形方式显示:

可以使用广播变量,例如,以有效的方式为每个节点提供大型数据集的副本(例如,带有关键字列表的字典)。 Spark 还尝试使用高效的广播算法分发广播变量以降低通信成本。

所以在您的情况下,您的代码可能如下所示:

Broadcast<String> broadcastVar = sc.broadcast("hello testing");
JavaDStream<String> javaDStream = consumerRecordJavaInputDStream.map(
    consumerRecord -> 
         return consumerRecord.value() + " --- " + broadcastVar.value();
    );

【讨论】:

以上是关于在哪种情况下,来自驱动程序节点的对象被序列化并发送到 apache spark 中的工作节点的主要内容,如果未能解决你的问题,请参考以下文章

递归与手动堆栈 - 在哪种情况下首选哪个?

在哪种情况下使用 JPA @JoinTable 注释?

在哪种情况下首选 ICommand 和 Local:Mvx

递归与手动堆栈 - 在哪种情况下哪个是首选?

TCP协议确认号在哪种情况下使用,以及TCP/IP详解对这个描述的疑问?

CachedNetworkImage 和 CachedNetworkImageProvider 有啥区别?应该分别用在哪种情况下?