docker 中的 Spark 无法打开我的文件。说文件不存在

Spark in docker can't open my file. It says the file doesn't exist

我使用 docker-compose 与 Jupyter Lab 的一项服务和 Apache Spark 的另一项服务构建了一个集群。这是我的 docker-compose.yaml.

version: '3'
services:
  jupyter-base-notebook:
    image: docker.io/jupyter/pyspark-notebook
    ports:
      - 8888:8888
    volumes:
      - ./data:/home/jovyan/work
  spark:
    image: docker.io/bitnami/spark: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'
  spark-worker:
    image: docker.io/bitnami/spark:3
    environment:
      - SPARK_MODE=worker
      - SPARK_MASTER_URL=spark://spark:7077
      - SPARK_WORKER_MEMORY=4G
      - SPARK_WORKER_CORES=1
      - SPARK_RPC_AUTHENTICATION_ENABLED=no
      - SPARK_RPC_ENCRYPTION_ENABLED=no
      - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no
      - SPARK_SSL_ENABLED=no

我想服务工作正常。我在浏览器中打开了 Jupyter Lab,并使用以下代码连接到我的 apache spark:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, when, regexp_replace
import os

spark = SparkSession.builder.master('spark://2833c5f3ee45:7077').getOrCreate()

我的连接成功,如下消息所示:

SparkSession - in-memory

SparkContext

Spark UI

Version
    v3.2.1
Master
    spark://2833c5f3ee45:7077
AppName
    pyspark-shell

但是,当我尝试加载我挂载的卷中的任何文件时,出现以下错误:

df = spark.read.csv('adult.csv', sep=',', header=True, inferSchema=True, encoding='ISO-8859-1')

File file:/home/jovyan/work/adult.csv does not exist

问题是当我在那里测试我的路径和文件时...没问题:

print(os.getcwd()) # /home/jovyan/work
print(os.listdir()) # ['.ipynb_checkpoints', 'Python_AP.ipynb', 'Datasets', 'adult.csv']

我错过了什么?我是 docker 技术方面的新手,我不明白出了什么问题。提前致谢。

TL;DR:我更新了我的 docker-compose 文件,现在它可以找到我的文件了。我也改变了阅读的路径。下面是新的 docker-compose.yaml 和解释。

version: '3'
services:
  jupyter-base-notebook:
    image: docker.io/jupyter/pyspark-notebook
    ports:
      - 8888:8888
    volumes:
      - ./data:/home/jovyan/work:rw
    networks:
      - spark-network
    user: root
    environment:
      - GRANT_SUDO=yes
      - JUPYTER_TOKEN=tad
      - SPARK_MASTER=spark://spark:7077
  spark:
    image: docker.io/bitnami/spark: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'
    networks:
      - spark-network
    volumes:
      - ./data:/home/jovyan/work:rw
  spark-worker:
    image: docker.io/bitnami/spark:3
    environment:
      - SPARK_MODE=worker
      - SPARK_MASTER_URL=spark://spark:7077
      - SPARK_WORKER_MEMORY=4G
      - SPARK_WORKER_CORES=1
      - SPARK_RPC_AUTHENTICATION_ENABLED=no
      - SPARK_RPC_ENCRYPTION_ENABLED=no
      - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no
      - SPARK_SSL_ENABLED=no
    networks:
      - spark-network
    volumes:
      - ./data:/home/jovyan/work:rw

networks:
  spark-network:
    driver: bridge

以下是所做的改进:

  • 与所有容器共享卷并确保 read-write 选项。
  • 已授予 jupyter-lab 用户 root 访问权限,因此 he/she 可以执行任何需要的更改。
  • 在 jupyter-lab 容器中设置 Spark_Master 环境变量以确保它可以到达 spark 主容器。
  • 为所有容器添加了一个公共网络以确保它们之间的通信。

最后我使用绝对路径读取我的文件如下:

file = 'file:////home/jovyan/work/adult.csv'
df = spark.read.csv(file, sep=',', header=True, inferSchema=True, encoding='ISO-8859-1')