PySpark:将数据拉到驱动程序,然后上传到数据框

时间:2018-06-22 18:44:37

标签: apache-spark pyspark

我正在尝试根据存储在外部数据库中的数据创建pyspark数据框。我使用pyodbc模块连接到数据库并提取所需的数据,然后使用spark.createDataFrame将数据发送到群集进行分析。

我使用--deploy-mode client运行脚本,因此驱动程序在主节点上运行,但是执行程序可以分发到其他计算机上。问题是pyodbc没有安装在任何工作节点上(这很好,因为我无论如何都不希望它们都查询数据库),所以当我尝试在脚本中导入该模块时,导入错误(除非所有执行程序都在主节点上)。

我的问题是如何指定我希望代码的特定部分(在这种情况下,导入pyodbc并查询数据库)仅在驱动程序上运行?我在想些什么

if __name__ == '__driver__':
  <do stuff>
else:
  <wait until stuff is done> 

2 个答案:

答案 0 :(得分:0)

您在python驱动程序 DO 中的导入仅在主服务器上运行。您唯一一次在执行程序上看到有关缺少导入的错误的情况是,如果您从调用驱动程序的函数中的那些导入之一引用某些对象/函数。我会仔细查看您在RDD / DataFrame调用中运行的任何python代码,这些代码都是意外的引用。如果您发布代码,我们可以为您提供更具体的指导。

此外,通过驱动程序路由数据通常不是一个好主意,因为它无法很好地扩展。如果您有大量数据,那么您将尝试强制执行所有操作,从而破坏了分布式处理的目的!

根据所使用的数据库,可能有一个Spark Connector实现,可将其直接加载到数据帧中。如果您使用的是ODBC,那么也许您使用的是SQL Server?例如,在这种情况下,您应该能够使用JDBC驱动程序,例如本文中的示例:

https://stephanefrechette.com/connect-sql-server-using-apache-spark/#.Wy1S7WNKjmE

答案 1 :(得分:0)

这不是火花应如何工作的方式。 Spark集合(RDDDataFrame)是固有分布的。您正在描述的是在本地创建数据集,方法是将整个数据集读取到驱动程序内存中,然后将其发送给执行者以通过创建RDD或{{1 }}。那没有多大意义。

如果要确保spark与数据库之间只有一个连接,则将并行度设置为1。然后可以在进一步的转换步骤中提高并行度。