在Docker上运行Spark时,我在将文件读入 Dataframe 时遇到问题。
下面是我的docker-compose.yml:
version: '2'
services:
spark:
image: docker.io/bitnami/spark:3.3
environment:
- SPARK_MODE=master
- SPARK_RPC_AUTHENTICATION_ENABLED=no
- SPARK_RPC_ENCRYPTION_ENABLED=no
- SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no
- SPARK_SSL_ENABLED=no
ports:
- '8080:8080'
- '7077:7077'
spark-worker:
image: docker.io/bitnami/spark:3.3
environment:
- SPARK_MODE=worker
- SPARK_MASTER_URL=spark://spark:7077
- SPARK_WORKER_MEMORY=1G
- SPARK_WORKER_CORES=1
- SPARK_RPC_AUTHENTICATION_ENABLED=no
- SPARK_RPC_ENCRYPTION_ENABLED=no
- SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no
- SPARK_SSL_ENABLED=no
这是基本的定义文件provided与Bitnami Spark Docker图像添加7077端口。
当我运行这个简单的脚本时,它不会从磁盘读取任何内容,它可以正常工作:
from pyspark.sql import SparkSession
def main():
spark = SparkSession.builder.master("spark://localhost:7077").appName("test").getOrCreate()
d = [
[1, 1],
[2, 2],
[3, 3],
]
df = spark.createDataFrame(d)
df.show()
spark.stop()
if __name__ == "__main__":
main()
输出如预期:
+---+---+
| _1| _2|
+---+---+
| 1| 1|
| 2| 2|
| 3| 3|
+---+---+
从这个我假设问题不是与Spark集群。然而,当我试图从本地驱动器读取文件,它不工作:
from pyspark.sql import SparkSession
def main():
spark = SparkSession.builder.master("spark://localhost:7077").appName("test").getOrCreate()
employees = spark.read.csv('./data/employees.csv', header=True)
salaries = spark.read.csv('./data/salaries.csv', header=True)
employees.show()
salaries.show()
spark.stop()
if __name__ == "__main__":
main()
出现以下错误:
py4j.protocol.Py4JJavaError:调用o27.csv时出错。:org.apache.spark.SparkException:由于分段失败而中止作业:阶段0.0中的任务0失败了4次,最近一次失败:阶段0.0(TID 3)中的任务0.3丢失(192.168.112.2执行器0):java.io.FileNotFoundException:文件文件:/用户/用户名/项目/spark/测试/数据/雇员.csv不存在
当我用本地PySpark库运行脚本时,通过定义Spark会话,如下所示:spark = SparkSession.builder.appName("test").getOrCreate()
,它工作了。我应该以某种方式将数据目录作为卷添加到容器中吗?我也试过了,但我还没有让它工作。
有什么建议吗?
1条答案
按热度按时间i34xakig1#
看起来你用
docker-compose
启动了一些docker容器,但没有挂载任何卷。在这种情况下Spark找不到这些文件是有道理的,因为它们不存在于容器中。假设你的容器是另一台物理机器,而不是你正在运行Spark脚本的那台。它怎么能找到那些文件呢?例如,你可以在另一台计算机里放一个U盘,里面有必要的数据。
为了让你的容器能够访问这些文件,你需要在你的容器上挂载一个卷。这有点(不严格地说)像在另一台机器里放一个U盘。
您可以通过在您的docker-compose.yml中使用
volumes
关键字来实现这一点:请注意
./:/mounted-data
位。模式为path-on-your-machine:path-on-container
。(您的数据所在的位置)添加到容器中的/mounted-data
。请注意,我将其添加到了spark
和spark-worker
服务中,因为我不熟悉bitnami的设置,但是只在spark-worker
服务上添加该卷可能就足够了。现在容器上的数据已经可用,您只需要在代码中正确地指向它,就可以在较大的spark脚本中读取数据了:
如果此处出现问题,请尝试以下操作:
docker exec -it container-name bash
cd
添加到已装载的数据文件夹。如果使用上面的示例,则为cd /mounted-data
ls -al
查看其中的内容我希望这对你有帮助!:)