我正在尝试根据存储在外部数据库中的数据创建pyspark数据框。我使用pyodbc
模块连接到数据库并提取所需的数据,然后使用spark.createDataFrame
将数据发送到群集进行分析。
我使用--deploy-mode client
运行脚本,因此驱动程序在主节点上运行,但是执行程序可以分发到其他计算机上。问题是pyodbc
没有安装在任何工作节点上(这很好,因为我无论如何都不希望它们都查询数据库),所以当我尝试在脚本中导入该模块时,导入错误(除非所有执行程序都在主节点上)。
我的问题是如何指定我希望代码的特定部分(在这种情况下,导入pyodbc
并查询数据库)仅在驱动程序上运行?我在想些什么
if __name__ == '__driver__':
<do stuff>
else:
<wait until stuff is done>
答案 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集合(RDD
或DataFrame
)是固有分布的。您正在描述的是在本地创建数据集,方法是将整个数据集读取到驱动程序内存中,然后将其发送给执行者以通过创建RDD
或{{1 }}。那没有多大意义。
如果要确保spark与数据库之间只有一个连接,则将并行度设置为1。然后可以在进一步的转换步骤中提高并行度。