PySpark 和 Databricks addFile 和 SparkFiles.get 异常 java.io.FileNotFoundException

问题描述 投票:0回答:1

我正在努力:

  1. 将 SSL 证书从 S3 加载到集群。
  2. addFile
    ,因此所有节点都能看到该文件。
  3. 使用 JDBC 创建到 IBM db2 的连接 URL。

步骤 1 和步骤 2 成功运行。我可以使用

with open(cert_filepath, "r") as file
打开文件并打印它。

但是在第3步中我收到以下错误:

org.apache.spark.SparkException:作业因阶段失败而中止:阶段 0.0 中的任务 0 失败 4 次,最近一次失败:阶段 0.0 中丢失任务 0.3 (TID 3) (10.239.124.48 执行程序 1):com.ibm .db2.jcc.am.DisconnectNonTransientConnectionException: [jcc][t4][2043][11550][4.27.25] 异常 java.io.FileNotFoundException: 在端口 53,101 上打开到服务器/的套接字时出错,并显示消息:/local_disk0/spark- c30d1a7f-deea-4184-a9f9-2b6c9eab6c5e/userFiles-761620cf-2cb1-4623-9677-68694f0e4b3c/dwt01_db2_ssl.arm(没有这样的文件或目录)。错误代码=-4499,SQLSTATE=08001

端口是

53101
,但错误代码中带有逗号。

代码的核心部分:

sc = SparkContext.getOrCreate()
s3_client = boto3.client("s3")
s3_client.download_file(
    Bucket="my-bucket-s3",
    Key="my/path/db2/dwt01_db2_ssl.arm",
    Filename="dwt01_db2_ssl.arm",
)
sc.addFile("dwt01_db2_ssl.arm")
cert_filepath = SparkFiles.get("dwt01_db2_ssl.arm")
user_name = cls.get_aws_secret(secret_name=cls._db2_username_aws_secret_name, key="username", region="eu-central-1")
password = cls.get_aws_secret(secret_name=cls._db2_password_aws_secret_name, key="password", region="eu-central-1")
driver = "com.ibm.db2.jcc.DB2Driver"
jdbc_url = f"jdbc:db2://{hostname}:{port}/{database}:sslConnection=true;sslCertLocation={cert_filepath};"

df = (
    spark.read.format("jdbc")
    .option("driver", driver)
    .option("url", jdbc_url)
    .option("dbtable", f"({query}) as src")
    .option("user", user_name)
    .option("password", password)
    .load()
)

我似乎无法解决这可能是什么原因

FileNotFoundException
,因为至少在阅读和打印它时它是存在的。

python apache-spark amazon-s3 pyspark databricks
1个回答
0
投票

由于

此评论
中提到的原因,您遇到了异常java.io.FileNotFoundException

在集群模式下,未添加到spark-submit的本地文件将无法通过addFile找到。这是因为驱动程序(应用程序主机)已在集群上启动,并且在到达 addFile 调用时已经在运行。此时已经太晚了。申请已提交,本地文件系统为特定集群节点的文件系统。

因此,为了克服这个问题,我建议您使用 DBFS 路径(例如:

/dbfs/dwt01_db2_ssl.arm
)以实现工作人员之间的一致性和访问。

这是您的更新代码:

# sc = SparkContext.getOrCreate()
s3_client = boto3.client("s3")
s3_client.download_file(
    Bucket="my-bucket-s3",
    Key="my/path/db2/dwt01_db2_ssl.arm",
    Filename="dwt01_db2_ssl.arm",
)
# sc.addFile("dwt01_db2_ssl.arm")
# cert_filepath = SparkFiles.get("dwt01_db2_ssl.arm")
cert_filepath = "/dbfs/dwt01_db2_ssl.arm"

之后,您必须按如下方式配置 Spark SSL 属性才能继续,因为您的代码当前缺少此属性:

spark.conf.set("spark.ssl", "true")
spark.conf.set("spark.ssl.trustStore", cert_filepath)

然后剩下的代码如下:

user_name = cls.get_aws_secret(secret_name=cls._db2_username_aws_secret_name, key="username", region="eu-central-1")
password = cls.get_aws_secret(secret_name=cls._db2_password_aws_secret_name, key="password", region="eu-central-1")
driver = "com.ibm.db2.jcc.DB2Driver"
jdbc_url = f"jdbc:db2://{hostname}:{port}/{database}:sslConnection=true;"

df = (
    spark.read.format("jdbc")
    .option("driver", driver)
    .option("url", jdbc_url)
    .option("dbtable", f"({query}) as src")
    .option("user", user_name)
    .option("password", password)
    .load()
)

注意:如果您注意到,我已经删除了

sslCertLocation
中的
jdbc_url
,因为我认为不再需要它了,因为我们已经配置了 Spark SSL 属性来处理该问题。

现在,执行上述更改应该可以理想地解决该错误。

我怀疑由于

.arm
文件可能会出现另一个问题,因为它不是标准的信任存储格式。但如果您遇到任何问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.