我正在使用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.
}
这是怎么了?如何在函数中传递数据集/数据框?
答案 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
。