spark scala算子内部引用sparkSession属性为空

很懒的耗子 2017-06-05 06:24:28
代码目的是在datafram filter算子内进行数据的检测,需要在算子内部根据数据的不同调用不同hdfs不同路径的模型,在初始化hdfs fileSystem时需要用到hadoopConfiguration对象,问题来了,在算子内部引用sparkSession的属性时,只有sparkSession有值,saprkSession.sparkContext, sparkSession.sparkContext.hadoopConfiguration则为null,算子外部则都正常,试过在算子外部定义号hdfs fileSystem,在内部引用,则会出现hdfs fileSystem未序列化异常。测试代码和log如下,为方便理解log经过剪切。百度,谷歌相关问题几乎没有。。。麻烦各位大神了。
代码:
def main(args: Array[String]): Unit = {

var spark = SparkSession.builder()
.master("spark://192.168.3.30:7077").appName("RunKMeansByUser").getOrCreate()
spark.sparkContext.addJar("D:\\ftpdata\\大数据\\testJar\\testByUser.jar");

// 测试用数据取得
val results = 。。。。。
results.cache();

logger.error("------------------------测试数据量:" + results.count() + "---------------------------")
val kmeansByUser = new RunKMeansByUser();

val resultsSchema = results.schema;

logger.error("------------------------sparkParam filter out---------------------------" + spark)
logger.error("------------------------sparkContext filter out---------------------------" + spark.sparkContext)
logger.error("------------------------hadoopConfiguration filter out---------------------------" + spark.sparkContext.hadoopConfiguration)

val anomalies = results.filter(line => {
logger.error("------------------------sparkParam filter in---------------------------" + spark)
logger.error("------------------------sparkContext filter in---------------------------" + spark.sparkContext)
logger.error("------------------------hadoopConfiguration filter in---------------------------" + spark.sparkContext.hadoopConfiguration)

// val hdfs = FileSystem.get(new URI("hdfs://192.168.3.30:9000"), spark.sparkContext.hadoopConfiguration)

// 数据检测
// kmeansByUser.buildTrustmoAnomalyDetector(line, spark, resultsSchema)
true
})

logger.error("------------------------异常数据量:" + anomalies.count() + "---------------------------")
anomalies.show();
results.unpersist()
}

log
17/06/05 17:39:09 ERROR RunKMeansByUser$: ------------------------sparkParam filter out---------------------------org.apache.spark.sql.SparkSession@72f3f14c
17/06/05 17:39:09 ERROR RunKMeansByUser$: ------------------------sparkContext filter out---------------------------org.apache.spark.SparkContext@4cb4c4cc
17/06/05 17:39:09 ERROR RunKMeansByUser$: ------------------------hadoopConfiguration filter out---------------------------Configuration: core-default.xml, core-site.xml, mapred-default.xml, mapred-site.xml, yarn-default.xml, yarn-site.xml, hdfs-default.xml, hdfs-site.xml

17/06/06 01:39:34 ERROR RunKMeansByUser$: ------------------------sparkParam filter in---------------------------org.apache.spark.sql.SparkSession@43defe41
17/06/06 01:39:34 ERROR RunKMeansByUser$: ------------------------sparkContext filter in---------------------------null
17/06/06 01:39:34 ERROR Executor: Exception in task 3.0 in stage 4.0 (TID 17)
java.lang.NullPointerException
...全文
1657 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
gk91620 2019-01-18
  • 打赏
  • 举报
回复
引用 10 楼 LinkSe7en 的回复:
[quote=引用 9 楼 gk91620 的回复:] [quote=引用 4 楼 LinkSe7en 的回复:] [quote=引用 2 楼 zenghao5202880 的回复:] @link0007 算子内不能引用sparkSession? 那我这个需求应该怎么处理? 我需要在算子内根据当前数据读取hdfs上的关联模型做处理,在外部定义号hdfs传入算子内部吗?hdfs fileSystem的序列化应该怎么处理?
要搞清楚,Spark的算子是在executor上执行的,数据也是放在executor上。executor和driver并不在同一个jvm(local
  • 除外),所以算子是不能访问在driver上的SparkSession对象。 好好品味一下这个图:
  • 如果一定要“在算子里访问SparkSession”,那你只能把数据collect回Driver,然后用Scala 集合的算子去做。这种情况下只能适用于数据量不大(多大取决于你分配给Driver的内存)。 另外建议是通过join的方式获取关联数据并进行处理。[/quote] 请教下两个问题。1.算子内访问外部变量时,变量的值会被拷贝到每个task中,sparkSession也是外部变量,为什么没有拷贝呢?2.如果将sparkSession进行Broadcast,会怎么样呢?[/quote] 持有sparkContext的jvm会被视为独立的一个Spark应用程序。 SparkSession和context无法被序列化/反序列化,强制执行会报错,或者产生各种你意想不到的惊喜。 简单来讲是没有任何意义。 别打在算子里访问SparkSession/Context的主意了。所有想这样做的目的,都可以通过Join或者小表广播的形式来完成。[/quote] 我最终确实是使用的join来解决的业务。
LinkSe7en 2019-01-18
  • 打赏
  • 举报
回复
引用 9 楼 gk91620 的回复:
[quote=引用 4 楼 LinkSe7en 的回复:] [quote=引用 2 楼 zenghao5202880 的回复:] @link0007 算子内不能引用sparkSession? 那我这个需求应该怎么处理? 我需要在算子内根据当前数据读取hdfs上的关联模型做处理,在外部定义号hdfs传入算子内部吗?hdfs fileSystem的序列化应该怎么处理?
要搞清楚,Spark的算子是在executor上执行的,数据也是放在executor上。executor和driver并不在同一个jvm(local
  • 除外),所以算子是不能访问在driver上的SparkSession对象。 好好品味一下这个图:
  • 如果一定要“在算子里访问SparkSession”,那你只能把数据collect回Driver,然后用Scala 集合的算子去做。这种情况下只能适用于数据量不大(多大取决于你分配给Driver的内存)。 另外建议是通过join的方式获取关联数据并进行处理。[/quote] 请教下两个问题。1.算子内访问外部变量时,变量的值会被拷贝到每个task中,sparkSession也是外部变量,为什么没有拷贝呢?2.如果将sparkSession进行Broadcast,会怎么样呢?[/quote] 持有sparkContext的jvm会被视为独立的一个Spark应用程序。 SparkSession和context无法被序列化/反序列化,强制执行会报错,或者产生各种你意想不到的惊喜。 简单来讲是没有任何意义。 别打在算子里访问SparkSession/Context的主意了。所有想这样做的目的,都可以通过Join或者小表广播的形式来完成。
gk91620 2019-01-18
  • 打赏
  • 举报
回复
引用 4 楼 LinkSe7en 的回复:
[quote=引用 2 楼 zenghao5202880 的回复:] @link0007 算子内不能引用sparkSession? 那我这个需求应该怎么处理? 我需要在算子内根据当前数据读取hdfs上的关联模型做处理,在外部定义号hdfs传入算子内部吗?hdfs fileSystem的序列化应该怎么处理?
要搞清楚,Spark的算子是在executor上执行的,数据也是放在executor上。executor和driver并不在同一个jvm(local
  • 除外),所以算子是不能访问在driver上的SparkSession对象。 好好品味一下这个图:
  • 如果一定要“在算子里访问SparkSession”,那你只能把数据collect回Driver,然后用Scala 集合的算子去做。这种情况下只能适用于数据量不大(多大取决于你分配给Driver的内存)。 另外建议是通过join的方式获取关联数据并进行处理。[/quote] 请教下两个问题。1.算子内访问外部变量时,变量的值会被拷贝到每个task中,sparkSession也是外部变量,为什么没有拷贝呢?2.如果将sparkSession进行Broadcast,会怎么样呢?
qixingmoming 2017-09-05
  • 打赏
  • 举报
回复
请问楼主这个问题怎么解决的,能否指点一下
weixin_39998441 2017-08-31
  • 打赏
  • 举报
回复
请问下,您是怎么解决的, 可以分享下么? 遇到了同样的问题。
weixin_39998441 2017-08-28
  • 打赏
  • 举报
回复
楼主是怎么解决的。 我们也遇到这个问题了。 可以分享下么
很懒的耗子 2017-06-07
  • 打赏
  • 举报
回复
引用 4 楼 link0007 的回复:
[quote=引用 2 楼 zenghao5202880 的回复:] @link0007 算子内不能引用sparkSession? 那我这个需求应该怎么处理? 我需要在算子内根据当前数据读取hdfs上的关联模型做处理,在外部定义号hdfs传入算子内部吗?hdfs fileSystem的序列化应该怎么处理?
要搞清楚,Spark的算子是在executor上执行的,数据也是放在executor上。executor和driver并不在同一个jvm(local
  • 除外),所以算子是不能访问在driver上的SparkSession对象。 好好品味一下这个图:
  • 如果一定要“在算子里访问SparkSession”,那你只能把数据collect回Driver,然后用Scala 集合的算子去做。这种情况下只能适用于数据量不大(多大取决于你分配给Driver的内存)。 另外建议是通过join的方式获取关联数据并进行处理。[/quote] 非常感谢,问题已经解决。
很懒的耗子 2017-06-06
  • 打赏
  • 举报
回复
@LinkSe7en 麻烦指点指点,实在买招了。。。
很懒的耗子 2017-06-06
  • 打赏
  • 举报
回复
@link0007 算子内不能引用sparkSession? 那我这个需求应该怎么处理? 我需要在算子内根据当前数据读取hdfs上的关联模型做处理,在外部定义号hdfs传入算子内部吗?hdfs fileSystem的序列化应该怎么处理?
LinkSe7en 2017-06-06
  • 打赏
  • 举报
回复
又看见个在算子里引用SparkSession的。。。
LinkSe7en 2017-06-06
  • 打赏
  • 举报
回复
引用 2 楼 zenghao5202880 的回复:
@link0007
算子内不能引用sparkSession?
那我这个需求应该怎么处理? 我需要在算子内根据当前数据读取hdfs上的关联模型做处理,在外部定义号hdfs传入算子内部吗?hdfs fileSystem的序列化应该怎么处理?

要搞清楚,Spark的算子是在executor上执行的,数据也是放在executor上。executor和driver并不在同一个jvm(local
  • 除外),所以算子是不能访问在driver上的SparkSession对象。
    好好品味一下这个图:

  • 如果一定要“在算子里访问SparkSession”,那你只能把数据collect回Driver,然后用Scala 集合的算子去做。这种情况下只能适用于数据量不大(多大取决于你分配给Driver的内存)。
    另外建议是通过join的方式获取关联数据并进行处理。

1,261

社区成员

发帖
与我相关
我的任务
社区描述
Spark由Scala写成,是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架,Spark基于MapReduce算法实现的分布式计算。
社区管理员
  • Spark
  • shiter
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧