学习spark-shell 时候发现一个问题,从本地文件加载数据生成RDD 报错,文件找不到
原因:spark-shell 如果启动了集群模式, 真正负责计算的executor会在,该executor所在的 worker节点上读取文件,并不是在master节点上读取。
解决方案: 把数据文件传给各个worker节点
for i in {1..2}; do scp -r /root/spark slave$i:/root/; done
详细情况:
首先 进入spark-shell 集群环境,
./spark-shell --master spark://master:7077 --total-executor-cores 1
执行代码: 读取文件 生成RDD
scala> val rdd1 = sc.textFile("file:///home/hzp/Documents/input.txt")
rdd1: org.apache.spark.rdd.RDD[String] = file:///home/hzp/Documents/input.txt MapPartitionsRDD[1] at textFile at <console>:24
然后报错,
scala> rdd1.count()
2021-05-20 21:58:26,328 WARN scheduler.TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, 192.168.100.102, executor 0): java.io.FileNotFoundException: File file:/home/hzp/Documents/input.txt does not exist
at org.apache.hadoop.fs.RawLocalFileSystem.deprecatedGetFileStatus(RawLocalFileSystem.java:666)
at org.apache.hadoop.fs.RawLocalFileSystem.getFileLinkStatusInternal(RawLocalFileSystem.java:987)
从报错内容可以看到,IP是一个worker 节点找不到数据文件,
也就是说 sparkContext 生成DAG图 ,并将其发给 task schedule,
然后 task schedule 切分stage(也就是task set 任务集合),
然后,各个worker节点会向,task schedule请求任务,然后 task schedule会根据 “计算向数据靠拢原则”,将对应的计算 发送给计算所需的数据 所在的worker 节点上。
那么如果两个 worker几点上都没数据,那么task 会被随机分给一个worker 节点,然后 该节点找不到数据 就会报错