我试图将DataFrame的转换方法写入DataFrame。 而且我也想通过scalatest进行测试。
如您所知,在使用Scala API的Spark 2.x中,您可以按如下方式创建SparkSession对象:
Exec AProc_Getback '512888,512889'
此代码适用于单元测试。 但是,当我使用spark-submit运行此代码时,群集选项不起作用。 例如,
import org.apache.spark.sql.SparkSession
val spark = SparkSession.bulider
.config("spark.master", "local[2]")
.getOrCreate()
不会创建任何执行者。
我发现当我删除上述代码的spark-submit --master yarn --deploy-mode client --num-executors 10 ...
部分时会应用spark-submit参数。
但是,没有主设置,单元测试代码就不起作用。
我试图将spark(SparkSession)对象生成部分拆分为test和main。
但是需要火花的代码块太多了,例如config("master", "local[2]")
和import spark.implicit,_
。
有没有最好的做法来编写代码来创建spark对象来测试和运行spark-submit?
答案 0 :(得分:4)
一种方法是创建一个提供SparkContext / SparkSession的特征,并在测试用例中使用它,如下所示:
trait SparkTestContext {
private val master = "local[*]"
private val appName = "testing"
System.setProperty("hadoop.home.dir", "c:\\winutils\\")
private val conf: SparkConf = new SparkConf()
.setMaster(master)
.setAppName(appName)
.set("spark.driver.allowMultipleContexts", "false")
.set("spark.ui.enabled", "false")
val ss: SparkSession = SparkSession.builder().config(conf).enableHiveSupport().getOrCreate()
val sc: SparkContext = ss.sparkContext
val sqlContext: SQLContext = ss.sqlContext
}
然后您的测试类标题如下所示:
class TestWithSparkTest extends BaseSpec with SparkTestContext with Matchers{
答案 1 :(得分:1)
我制作了一个版本,测试后Spark会正确关闭。
import org.apache.spark.sql.{SQLContext, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}
import org.scalatest.{BeforeAndAfterAll, FunSuite, Matchers}
trait SparkTest extends FunSuite with BeforeAndAfterAll with Matchers {
var ss: SparkSession = _
var sc: SparkContext = _
var sqlContext: SQLContext = _
override def beforeAll(): Unit = {
val master = "local[*]"
val appName = "MyApp"
val conf: SparkConf = new SparkConf()
.setMaster(master)
.setAppName(appName)
.set("spark.driver.allowMultipleContexts", "false")
.set("spark.ui.enabled", "false")
ss = SparkSession.builder().config(conf).getOrCreate()
sc = ss.sparkContext
sqlContext = ss.sqlContext
super.beforeAll()
}
override def afterAll(): Unit = {
sc.stop()
super.afterAll()
}
}
答案 2 :(得分:1)
带有参数--master yarn的spark-submit命令正在设置纱线master。 即使您使用master(“ yarn”)之类的代码,这也会与您的代码master(“ x”)冲突。
如果您想使用toDF,toDS或其他func之类的import sparkSession.implicits._, 您可以只使用如下创建的本地sparkSession变量:
val spark = SparkSession.builder()。appName(“ YourName”)。getOrCreate()
未在spark-submit --master纱线中设置master(“ x”),而不在本地机器中设置。
我建议:不要在代码中使用全局sparkSession。这可能会导致某些错误或异常。
希望这对您有所帮助。 祝你好运!
答案 3 :(得分:0)
如何定义一个方法,在该对象中方法创建SparkSession的单例实例,如MySparkSession.get()
,并在每个单元测试中将其作为参数传递。
在main方法中,您可以创建一个单独的SparkSession实例,该实例可以有不同的配置。