Spark:广播变量:您似乎正试图从广播变量、操作或转换中引用 SparkContext

Posted

技术标签:

【中文标题】Spark:广播变量:您似乎正试图从广播变量、操作或转换中引用 SparkContext【英文标题】:Spark: Broadcast variables: It appears that you are attempting to reference SparkContext from a broadcast variable, action, or transforamtion 【发布时间】:2015-07-20 04:04:48 【问题描述】:
Class ProdsTransformer:

    def __init__(self):  
      self.products_lookup_hmap = 
      self.broadcast_products_lookup_map = None

    def create_broadcast_variables(self):
      self.broadcast_products_lookup_map = sc.broadcast(self.products_lookup_hmap)

    def create_lookup_maps(self):
    // The code here builds the hashmap that maps Prod_ID to another space.

pt = ProdsTransformer ()
pt.create_broadcast_variables()  

pairs = distinct_users_projected.map(lambda x: (x.user_id,    
                         pt.broadcast_products_lookup_map.value[x.Prod_ID]))

我收到以下错误:

“例外:您似乎正在尝试引用 来自广播变量、动作或转换的 SparkContext。 SparkContext 只能在驱动程序上使用,不能在它运行的代码中使用 对工人。有关详细信息,请参阅 SPARK-5063。”

任何关于如何处理广播变量的帮助都会很棒!

【问题讨论】:

代码和/或示例数据不足以让某人尝试复制错误和/或修复它。此外,如果您没有注意到,所有缩进都会从 python 中删除。 我添加了更多代码。 我想知道如果您将products_lookup_mapProdsTransformer 实例的属性中移出并改为全局属性,该错误是否会消失。您需要多张地图吗? 我需要多张地图。 好的,我认为错误的意思是在工作人员中禁止调用 sc 或 rdd 函数,即在任何 spark 函数中,如 map()flatmap()reduce() 等....您只能在主程序中调用sc.something。因此,例如,您可以链接地图,但不能在地图中拥有地图。显然广播是受到这种限制的。我已经看到 spark mangle 自定义类,因此有一些从正在移动的序列化数据中重新创建工人的类实例。 【参考方案1】:

通过在 map lambda 中引用包含广播变量的对象,Spark 将尝试序列化整个对象并将其发送给工作人员。由于该对象包含对 SparkContext 的引用,因此您会收到错误消息。而不是这个:

pairs = distinct_users_projected.map(lambda x: (x.user_id, pt.broadcast_products_lookup_map.value[x.Prod_ID]))

试试这个:

bcast = pt.broadcast_products_lookup_map
pairs = distinct_users_projected.map(lambda x: (x.user_id, bcast.value[x.Prod_ID]))

后者避免了对对象 (pt) 的引用,因此 Spark 只需要传送广播变量。

【讨论】:

【参考方案2】:

仅在创建所有上下文变量后定义检查点。 检查点后不要定义任何上下文变量,否则会抛出这种类型的错误

【讨论】:

以上是关于Spark:广播变量:您似乎正试图从广播变量、操作或转换中引用 SparkContext的主要内容,如果未能解决你的问题,请参考以下文章

Spark流处理中的广播变量

Spark广播变量实现原理及基础编程

Spark(20)——广播变量和累加器

Spark入门3(累加器和广播变量)

Spark学习之路 Spark的广播变量和累加器

Spark学习之路 Spark的广播变量和累加器[转]