在pyspark中调用scala/java代码

原文地址:Using Scala code in PySpark applications (diogoalexandrefranco.github.io)

前言

虽然有充分的理由使用Python API开发Spark应用程序,但不可否认的是,Scala是Spark的母语。如果您需要PySpark不支持的功能,或者只想在Python应用程序中使用Scala库,那么这篇文章将展示如何将两者结合起来,并充分利用两者。

一、在PySpark应用程序中调用Scala代码

Pyspark在解释器和JVM之间建立了一个geteway ,也就是 Py4J 。我们可以用它来操作Java对象。
下面让我们编写一个最简单的Scala对象:

package com.test.spark
object SayHello {
    def ditBonjour = println("Bonjour")
}

然后,我们使用maven或sbt等工具构建它并将其打包为JAR:

$ mvn package
Building jar: .../target/testspark-0.1.0-SNAPSHOT.jar

接下来,我们可以在启动pyspark shell的时候,使用--driver-class-path添加这个jar包。 同时,我们可能还需要在--jars参数包含这个jar包。

pyspark --master yarn --deploy-mode client --jars testspark-0.1.0-SNAPSHOT.jar --driver-class-path testspark-0.1.0-SNAPSHOT.jar

然后在交互界面中, 我们可以通过访问spark context(sc)的_jvm属性来访问我们的包:

>>> SayHello = sc._jvm.com.test.spark.SayHello
>>> SayHello.ditBonjour()
Bonjour

真正的项目从来没有那么简单!!!

在实际项目中,有几件事可能与上面的简单示例不同,这会带来一些复杂性。

依赖于外部库的Scala代码:

在这种情况下,我不可能总是通过简单地打包Scala代码并在–packages中提交具有依赖项的PySpark作业来获得成功。最简单的方法是打包一个也包含Scala依赖项的jar。我们可以使用sbt组装来实现这一点。

传递Spark对象:

在环境之间传递Spark对象时,必须将其显式装箱/取消装箱到java对象中。以下是几个常见的例子:

  • SparkContext
    // 如果您的Scala代码需要访问SparkContext(sc),那么python代码必须通过sc._ jsc,
    // 并且您的Scala方法应该接收一个JavaSparkContext参数并将其取消绑定到Scala SparkContext。
    import org.apache.spark.api.java.JavaSparkContext def method(jsc: JavaSparkContext) = { val sc = JavaSparkContext.toSparkContext(jsc) }
  • SQLContext
    // Scala SQLContext 可以通过发送 sqlContext._ssql_ctx 从 python 传递。 这将在 Scala 端无需任何转换即可使用。
  • RDDs
    // 您可以通过rdd将它们从Python传递到Scala_jrdd。在Scala方面,可以通过访问jrdd来解除JavaRDD(jrdd)的绑定。rdd。将其转换回Python时,可以执行以下操作:
    from pyspark.rdd import RDD
    
    pythonRDD = RDD(jrdd, sc)
  • DataFrames
    // 要从python发送数据帧(df),必须传递df_jdf属性。将Scala数据帧返回python时,可以通过以下方式在python端进行转换:
    from pyspark.sql import DataFrame
    
    pythonDf = DataFrame(jdf, sqlContext)

     

 

posted @ 2022-06-28 13:33  干了这瓶老干妈  阅读(598)  评论(0编辑  收藏  举报
Live2D