如何广播一个DataFrame?

时间:2019-12-17 11:15:32

标签: apache-spark apache-spark-sql

我正在使用spark-sql-2.4.1版本。 创建如下的广播变量

Broadcast<Map<String,Dataset>> bcVariable = javaSparkContext.broadcast(//read dataset);

我将bcVariable传递给函数

Service.calculateFunction(sparkSession, bcVariable.getValue());


public   static class Service {
        public static calculateFunction(
          SparkSession sparkSession,
          Map<String, Dataset> dataSet ) {

        System.out.println("---> size : " + dataSet.size());  //printing size 1


        for( Entry<String, Dataset> aEntry : dataSet.entrySet() ) {
           System.out.println( aEntry.getKey());   //  printing key 
            aEntry.getValue().show()   // throw null pointer exception
           }
    }

这是怎么了?如何在函数中传递数据集/数据框?

尝试2:

Broadcast<Dataset> bcVariable = javaSparkContext.broadcast(//read dataset);

我将bcVariable传递给函数

 Service.calculateFunction(sparkSession, bcVariable.getValue());

公共静态类服务{         公共静态calculateFunction(           SparkSession sparkSession,           数据集dataSet){

    System.out.println("---> size : " + dataSet.size());  // throwing null pointer exception.



}

这是怎么了?如何在函数中传递数据集/数据框?

尝试3:

Dataset metaData = //read dataset from oracle table i.e. meta-data.

我将metaData传递给函数

Service.calculateFunction(sparkSession,metaData);

public   static class Service {
        public static calculateFunction(
          SparkSession sparkSession,
          Dataset metaData ) {

        System.out.println("---> size : " + metaData.size());  // throwing null pointer exception.



    }

这是怎么了?如何在函数中传递数据集/数据框?

1 个答案:

答案 0 :(得分:2)

要广播的值必须是任何Scala对象,而不是DataFrame

Service.calculateFunction(sparkSession, metaData)是在执行程序上执行的,因此metaData是null(因为它没有被序列化并通过电线从驱动程序发送到执行程序)。

  

广播[T](值:T):广播[T]

     

向集群广播一个只读变量,返回一个org.apache.spark.broadcast.Broadcast对象以在分布式函数中读取它。该变量将仅发送到每个集群一次。

考虑DataFrame数据抽象以表示一种分布式计算,该计算以类似SQL的语言(数据集API或SQL)进行描述。根本没有任何意义,而是将其放在可以提交计算以执行(作为执行程序上的任务)的驱动程序上。

您只需要使用DataFrame“转换”此计算表示的数据(以DataFrame.collect项即可。)

一旦收集到数据,就可以使用.value方法进行广播和引用。


代码如下:

val dataset = // reading data
Broadcast<Map<String,Dataset>> bcVariable = 
  javaSparkContext.broadcast(dataset.collect);
Service.calculateFunction(sparkSession, bcVariable.getValue());

与您的代码相比,唯一的变化是collect