pyspark 如何在Docker上运行Spark时访问本地计算机上的文件

mwkjh3gx  于 2022-11-28  发布在  Spark
关注(0)|答案(1)|浏览(251)

在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(),它工作了。我应该以某种方式将数据目录作为卷添加到容器中吗?我也试过了,但我还没有让它工作。
有什么建议吗?

i34xakig

i34xakig1#

看起来你用docker-compose启动了一些docker容器,但没有挂载任何卷。在这种情况下Spark找不到这些文件是有道理的,因为它们不存在于容器中。
假设你的容器是另一台物理机器,而不是你正在运行Spark脚本的那台。它怎么能找到那些文件呢?例如,你可以在另一台计算机里放一个U盘,里面有必要的数据。
为了让你的容器能够访问这些文件,你需要在你的容器上挂载一个卷。这有点(不严格地说)像在另一台机器里放一个U盘。
您可以通过在您的docker-compose.yml中使用volumes关键字来实现这一点:

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'
    volumes:
      - ./:/mounted-data

  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
    volumes:
      - ./:/mounted-data

请注意./:/mounted-data位。模式为path-on-your-machine:path-on-container。(您的数据所在的位置)添加到容器中的/mounted-data。请注意,我将其添加到了sparkspark-worker服务中,因为我不熟悉bitnami的设置,但是只在spark-worker服务上添加该卷可能就足够了。
现在容器上的数据已经可用,您只需要在代码中正确地指向它,就可以在较大的spark脚本中读取数据了:

employees = spark.read.csv('/mounted-data/data/employees.csv', header=True)
    salaries = spark.read.csv('/mounted-data/data/salaries.csv', header=True)

如果此处出现问题,请尝试以下操作:

  • 使用以下命令进入容器内部:docker exec -it container-name bash
  • cd添加到已装载的数据文件夹。如果使用上面的示例,则为cd /mounted-data
  • 如果此操作不起作用,则说明在装载卷时出现了问题。
  • 使用ls -al查看其中的内容
  • 如果这不起作用,您可能在您的卷上有权限问题,这在this SO post中讨论。

我希望这对你有帮助!:)

相关问题