我可以使用jupyter实验室与databricks spark cluster使用scala进行交互吗?

ohfgkhjo  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(560)

我可以使用jupyter实验室连接到远程托管的databricks spark集群吗?
有一些关于databricksconnect的知识库文章,它允许scala或java客户机进程控制spark集群。举个例子:
https://docs.databricks.com/dev-tools/databricks-connect.html
虽然那篇kb文章涵盖了很多场景,但它没有解释如何使用jupyter笔记本与使用scala编程语言的databricks集群进行交互。我熟悉scala编程,但不熟悉python。

w6lpcovy

w6lpcovy1#

是的,这似乎是可能的,虽然它没有很好的记录。这些步骤对我来说在Windows上很有效。我将databricksv.7.1与scala 2.12.10结合使用。
第一步。安装anaconda:https://repo.anaconda.com/
第二步。因为python似乎是笔记本电脑的首选语言,
您需要手动安装和配置scala内核
我可以用杏仁仁来解决问题:https://almond.sh/
安装almond时,请小心选择scala的一个版本
与远程集群中要连接到的dbr运行时相对应的。
第三步。现在,按照databricks connect文档获得一个scala程序
编译并通过intellij/sbt环境连接到远程集群。
文档可以在这里找到。https://docs.databricks.com/dev-tools/databricks-connect.html
这是一种完全受支持且相当传统的方法,可用于开发自定义模块。
第四步。一旦您创建了一个工作的scala流程,您将熟悉sbt。build.sbt用于引用“databricks connect”发行版。配送地点如下:

unmanagedBase := new java.io.File("C:\\Users\\minime\\AppData\\Local\\Programs\\Python\\Python37\\Lib\\site-packages\\pyspark\\jars")

虽然intellij/sbt可以直接将这些依赖项编译到程序中,但在almond/jupyter内核中做同样的事情需要做更多的工作。
在返回jupyter笔记本之前,运行新的scala进程并允许它创建一个spark会话。然后在进程结束之前,使用“process explorer”找到相关java.exe的句柄,然后在下面的视图/窗格中显示句柄,然后将所有句柄复制到记事本中(process explorer中的ctrl+a,记事本中的ctrl+v)。这将为您提供databricks发行版中的模块子集,这些模块在运行时实际加载到您的进程中。
第五步。现在您已经有了相关的模块,您需要配置almondscala内核以将它们加载到内存中。创建一个新的jupyter笔记本并选择scala内核,然后使用如下代码加载所有模块:

interp.load.cp(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath( "C:/Users/minime/AppData/Local/Programs/Python/Python37/Lib/site-packages/pyspark/jars/whatever001-1.1.1.jar")))
interp.load.cp(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath( "C:/Users/minime/AppData/Local/Programs/Python/Python37/Lib/site-packages/pyspark/jars/whatever002-1.1.1.jar")))
interp.load.cp(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath( "C:/Users/minime/AppData/Local/Programs/Python/Python37/Lib/site-packages/pyspark/jars/whatever003-1.1.1.jar")))
...

请注意,发行版中有很多jar(可能有100个!?)。
您可能希望直接从maven加载其他库(假设它们与scala 2.12.10和databricks connect发行版兼容)

// Microsoft JDBC
 interp.load.ivy("com.microsoft.sqlserver" % "mssql-jdbc" % "8.2.1.jre8")

// Other libraries
 interp.load.ivy("joda-time" % "joda-time" % "2.10.5")
 interp.load.ivy("org.scalaj" %% "scalaj-http" % "2.3.0")
 interp.load.ivy("org.json4s" %% "json4s-native" % "3.5.3")
 interp.load.ivy("com.microsoft.azure"  % "msal4j"   % "1.6.1")

// Other libraries
interp.load.ivy("org.apache.hadoop" % "hadoop-azure" % "3.2.1")

公正的警告。。。在将库加载到almond内核中时,有时按特定顺序加载它们是很重要的。我上面的示例并不打算告诉您通过interp.load加载它们的顺序。
第六步。如果一切按计划进行,您现在应该能够创建一个运行在jupyter笔记本上的spark会话,使用的代码类似于您在上面“步骤3”中编写的内容。

import org.apache.spark.sql._
val p_SparkSession = SparkSession.builder()
        .appName("APP_" + java.util.UUID.randomUUID().toString)
        .master("local") 
        .config("spark.cores.max","4") 
        .getOrCreate()

您的almond内核现在通过databricks connect发行版连接到远程集群。只要不需要将任何函数或数据类型序列化到远程集群,一切都可以工作。在这种情况下,可能会出现各种序列化错误和空指针异常。举个例子:
java.lang.nullpointerexception com.databricks.service.sparkserviceclasssync$.checksynced(sparkserviceclasssync)。scala:244)org.apache.spark.sql.util.sparkserviceobjectoutputstream.WriterPlaceClassDescriptor(sparkserviceobjectoutputstream)。scala:82) ... org.apache.spark.sql.util.protoserializer.serializeplan(protoserializer。scala:377)com.databricks.service.sparkservicerpclientstub.$anonfun$executeplan$1(sparkservicerpclientstub。scala:193)
这个答案将是几个答案中的第一个。我希望有其他的scala/spark/databricksMaven可以帮助解决这个配置中的剩余问题,这样我的笔记本中声明的任何函数和数据类型都可以被远程集群使用!

2fjabf4q

2fjabf4q2#

在我的第一个回答中,我指出使用scala笔记本(在jupyter lab和almond中)的主要挑战是,我们缺少序列化任何函数或数据类型并将它们发送到由databricks托管的远程集群的功能。
我应该指出,当我遇到这个限制时,我经常使用两种解决方法。
我恢复使用“Spark壳”。它是databricks connect分发的标准组件。然后可以使用:load和:paste命令加载scala代码的相关部分。出于某种令人高兴的原因,“sparkshell”完全能够序列化函数和数据类型,以便动态地将它们发送到远程集群。这是杏仁仁在jupyter笔记本中无法为我们做到的。
另一个解决方法是将dataframes.collect()返回到驱动程序(在jupyter笔记本内核的内存中)。一旦Dataframe被收集,我就可以对它们执行额外的转换,即使借助于只有在jupyter笔记本中才能找到的“original”函数和“original”数据类型。在这种情况下,我将无法获得分布式处理的性能优势。但是,虽然代码仍在开发中,但我通常不会处理非常大的数据集,因此如果驱动程序正在运行我的函数,或者工作程序正在运行,也不会有太大的区别。
希望这是清楚的。我希望databricks最终能在jupyter实验室看到允许scala程序员远程开发代码的好处。我认为他们需要选择scala内核之一,并承担起支持这种场景的重任。到目前为止,他们可能认为自己在门户中的笔记本经验足以满足所有scala程序员的需求。

相关问题