如何从Java String数组创建Spark广播变量?

Ume*_*cha 0 apache-spark

嗨,我有Java字符串数组,其中包含45个字符串,基本上是列名

String[] fieldNames = {"colname1","colname2",...}; 
Run Code Online (Sandbox Code Playgroud)

目前,我将上面的String数组存储在静态字段中的Spark驱动程序中.我的工作运行缓慢所以试图重构代码.我在创建DataFrame时使用上面的String数组

DataFrame dfWithColNames = sourceFrame.toDF(fieldNames); 
Run Code Online (Sandbox Code Playgroud)

我想使用广播变量做上面的事情,它不会向每个执行者发送巨大的字符串数组我相信我们可以做如下的事情来创建广播

String[] brArray = sc.broadcast(fieldNames,String[].class);//gives compilation error 

DataFrame df = sourceFrame.toDF(???);//how do I use above broadcast can I use it as is by passing brArray 
Run Code Online (Sandbox Code Playgroud)

请指导我是Spark新手.非常感谢.

Gle*_*olt 8

返回变量sc.broadcast是类型Broadcast<String[]>而不是String[].如果要访问该值,只需在变量上调用value()即可.从你的例子来看,它将是:

Broadcast<String[]> broadcastedFieldNames = sc.broadcast(fieldNames)
DataFrame df = sourceFrame.toDF(broadcastedFieldNames.value())
Run Code Online (Sandbox Code Playgroud)

请注意,如果您使用Java编写此函数,则可能需要将SparkContext包装在JavaSparkContext中.它使一切变得更容易,然后您可以避免必须将ClassTag传递给广播功能.

您可以在http://spark.apache.org/docs/latest/programming-guide.html#broadcast-variables上阅读有关广播变量的更多信息.


Dmi*_*try 7

这是一个有点老问题,但是,我希望我的解决方案可以帮助某人.

为了使用Spark 2+广播任何对象(可以是单个POJO或集合),首先需要使用以下方法为您创建classTag:

private static <T> ClassTag<T> classTag(Class<T> clazz) {
   return scala.reflect.ClassManifestFactory.fromClass(clazz);
}
Run Code Online (Sandbox Code Playgroud)

接下来,您使用SparkSession中的JavaSparkContext来像以前一样广播您的对象:

   sparkSession.sparkContext().broadcast(
            yourObject,
            classTag(YourObject.class)
    )
Run Code Online (Sandbox Code Playgroud)

如果是集合,比如java.util.List,则使用以下命令:

    sparkSession.sparkContext().broadcast(
            yourObject,
            classTag(List.class)
    )
Run Code Online (Sandbox Code Playgroud)