Spark 工作节点无法访问主节点上的文件
Spark worker nodes unable to access file on master node
我正在尝试通过我的 Spark Scala 代码连接到 Presto DB,然后 运行将其连接到 EMR 集群。
我能够创建 RDD,但是当工作节点试图获取数据时,代码失败说找不到文件(密钥库不存在),尽管它存在于主节点中。有没有办法可以将密钥库文件复制到子节点?
以下是我的代码和我遵循的步骤
第一步
我使用以下命令将证书复制到 tmp 文件夹
s3-dist-cp --src s3://test/rootca_ca.jks --dest /tmp/
然后我运行下面的代码用下面的命令
spark-submit --executor-memory=10G --driver-memory=10G --executor-cores=2 --jars s3://test1/jars/presto-jdbc-338-e.0.jar --class com.asurion.prestotest --master yarn s3://test1/script/prestotest.jar
package com.asurion
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.log4j._
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
import org.apache.spark.sql.SparkSession
import org.apache.spark.storage.StorageLevel
import java.time.LocalDateTime
import java.util.concurrent._
object prestotest {
def main(args: Array[String]) {
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)
val conf = new SparkConf().setAppName("testapp")
val sc = new SparkContext(conf);
val sqlcontext = SparkSession.builder().getOrCreate()
val carrier_info =" select * from test_tbl "
val enrdata = sqlcontext.read.format("jdbc").option("url", "jdbc:presto://test.atlas.prd.aws.test.net:18443/hive").option("SSL","true").option("SSLTrustStorePath","/tmp/rootca_ca.jks").option("SSLTrustStorePassword","pass1").option("query", carrier_info).option("user", "user1").option("password", "pass2").option("driver", "io.prestosql.jdbc.PrestoDriver").load()
println("Writing Statistics" )
enrdata.show(5)
println("Writing done" )
}
}
错误:
scheduler.TaskSetManager (Logging.scala:logWarning(66)): Lost task 0.0 in stage 0.0 (TID 0, 100.64.187.253, executor 1): java.sql.SQLException: Error setting up SSL: /tmp/rootca_ca.jks (No such file or directory)
at io.prestosql.jdbc.PrestoDriverUri.setupClient(PrestoDriverUri.java:235)
at io.prestosql.jdbc.PrestoDriver.connect(PrestoDriver.java:88)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$createConnectionFactory.apply(JdbcUtils.scala:63)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$createConnectionFactory.apply(JdbcUtils.scala:54)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD.compute(JDBCRDD.scala:272)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
at org.apache.spark.scheduler.Task.run(Task.scala:121)
at org.apache.spark.executor.Executor$TaskRunner$$anonfun.apply(Executor.scala:408)
at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1360)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:414)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: io.prestosql.jdbc.$internal.client.ClientException: Error setting up SSL: /tmp/rootca_ca.jks (No such file or directory)
at io.prestosql.jdbc.$internal.client.OkHttpUtil.setupSsl(OkHttpUtil.java:241)
at io.prestosql.jdbc.PrestoDriverUri.setupClient(PrestoDriverUri.java:203)
... 23 more
Caused by: java.io.FileNotFoundException: /tmp/rootca_ca.jks (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at io.prestosql.jdbc.$internal.client.OkHttpUtil.loadTrustStore(OkHttpUtil.java:308)
at io.prestosql.jdbc.$internal.client.OkHttpUtil.setupSsl(OkHttpUtil.java:220)
在 EMR 上的 Spark 在核心节点之一(默认情况下)而不是在主代码上创建驱动程序。
驱动程序(在 CORE 节点上)无法访问主节点中的文件。
那么你有什么选择-
- 在启动 EMR 集群时编写一个 bootstrap 脚本以将
rootca_ca.jks
文件 (s3 cp
) 复制到每个工作节点 (核心和任务) 并且您不要更改程序中的任何内容
- 当您使用
s3-dist-cp
复制文件时,它会将您的文件放在 HDFS 中而不是 linux 文件系统中。
要访问该文件,您需要添加文件系统前缀。 hdfs:///tmp/rootca_ca.jks
.
您不需要输入名称节点地址和端口,因为它由 core-site.xml 中的 EMR 配置
- 由于您的文件已经在S3中,您可以使用EMRFS(它不过是S3作为hadoop文件系统)。要使用 EMRFS 访问文件,只需将 S3 url
s3://test/rootca_ca.jks
.
但请确保您的 EC2 EMR IAM 角色有权从 S3 获取对象
它也有自己的成本,但由于你的文件很小,你可以利用这个
选项 1: 随着时间的推移很难维护,如果您的文件需要在 运行 集群上更改,您将不得不这样做它在每个工作节点上手动执行。
方案2:由于HDFS是共享文件系统,您可能需要在一个地方维护文件。
选项 3: 与选项 2 没有太大区别,只是您的文件保留并从 S3 读取。您不必在 HDFS 中复制文件。
我正在尝试通过我的 Spark Scala 代码连接到 Presto DB,然后 运行将其连接到 EMR 集群。 我能够创建 RDD,但是当工作节点试图获取数据时,代码失败说找不到文件(密钥库不存在),尽管它存在于主节点中。有没有办法可以将密钥库文件复制到子节点? 以下是我的代码和我遵循的步骤
第一步 我使用以下命令将证书复制到 tmp 文件夹
s3-dist-cp --src s3://test/rootca_ca.jks --dest /tmp/
然后我运行下面的代码用下面的命令
spark-submit --executor-memory=10G --driver-memory=10G --executor-cores=2 --jars s3://test1/jars/presto-jdbc-338-e.0.jar --class com.asurion.prestotest --master yarn s3://test1/script/prestotest.jar
package com.asurion
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.log4j._
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
import org.apache.spark.sql.SparkSession
import org.apache.spark.storage.StorageLevel
import java.time.LocalDateTime
import java.util.concurrent._
object prestotest {
def main(args: Array[String]) {
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)
val conf = new SparkConf().setAppName("testapp")
val sc = new SparkContext(conf);
val sqlcontext = SparkSession.builder().getOrCreate()
val carrier_info =" select * from test_tbl "
val enrdata = sqlcontext.read.format("jdbc").option("url", "jdbc:presto://test.atlas.prd.aws.test.net:18443/hive").option("SSL","true").option("SSLTrustStorePath","/tmp/rootca_ca.jks").option("SSLTrustStorePassword","pass1").option("query", carrier_info).option("user", "user1").option("password", "pass2").option("driver", "io.prestosql.jdbc.PrestoDriver").load()
println("Writing Statistics" )
enrdata.show(5)
println("Writing done" )
}
}
错误:
scheduler.TaskSetManager (Logging.scala:logWarning(66)): Lost task 0.0 in stage 0.0 (TID 0, 100.64.187.253, executor 1): java.sql.SQLException: Error setting up SSL: /tmp/rootca_ca.jks (No such file or directory)
at io.prestosql.jdbc.PrestoDriverUri.setupClient(PrestoDriverUri.java:235)
at io.prestosql.jdbc.PrestoDriver.connect(PrestoDriver.java:88)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$createConnectionFactory.apply(JdbcUtils.scala:63)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$createConnectionFactory.apply(JdbcUtils.scala:54)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD.compute(JDBCRDD.scala:272)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
at org.apache.spark.scheduler.Task.run(Task.scala:121)
at org.apache.spark.executor.Executor$TaskRunner$$anonfun.apply(Executor.scala:408)
at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1360)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:414)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: io.prestosql.jdbc.$internal.client.ClientException: Error setting up SSL: /tmp/rootca_ca.jks (No such file or directory)
at io.prestosql.jdbc.$internal.client.OkHttpUtil.setupSsl(OkHttpUtil.java:241)
at io.prestosql.jdbc.PrestoDriverUri.setupClient(PrestoDriverUri.java:203)
... 23 more
Caused by: java.io.FileNotFoundException: /tmp/rootca_ca.jks (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at io.prestosql.jdbc.$internal.client.OkHttpUtil.loadTrustStore(OkHttpUtil.java:308)
at io.prestosql.jdbc.$internal.client.OkHttpUtil.setupSsl(OkHttpUtil.java:220)
在 EMR 上的 Spark 在核心节点之一(默认情况下)而不是在主代码上创建驱动程序。
驱动程序(在 CORE 节点上)无法访问主节点中的文件。
那么你有什么选择-
- 在启动 EMR 集群时编写一个 bootstrap 脚本以将
rootca_ca.jks
文件 (s3 cp
) 复制到每个工作节点 (核心和任务) 并且您不要更改程序中的任何内容 - 当您使用
s3-dist-cp
复制文件时,它会将您的文件放在 HDFS 中而不是 linux 文件系统中。
要访问该文件,您需要添加文件系统前缀。hdfs:///tmp/rootca_ca.jks
.
您不需要输入名称节点地址和端口,因为它由 core-site.xml 中的 EMR 配置
- 由于您的文件已经在S3中,您可以使用EMRFS(它不过是S3作为hadoop文件系统)。要使用 EMRFS 访问文件,只需将 S3 url
s3://test/rootca_ca.jks
.
但请确保您的 EC2 EMR IAM 角色有权从 S3 获取对象
它也有自己的成本,但由于你的文件很小,你可以利用这个
选项 1: 随着时间的推移很难维护,如果您的文件需要在 运行 集群上更改,您将不得不这样做它在每个工作节点上手动执行。
方案2:由于HDFS是共享文件系统,您可能需要在一个地方维护文件。
选项 3: 与选项 2 没有太大区别,只是您的文件保留并从 S3 读取。您不必在 HDFS 中复制文件。