介绍
使用Docker搭建Spark集群和MinIO云存储服务,并通过Spark访问MinIO,实现读写功能。
MinIO是什么
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
详细资料参考这里
Docker实现
本项目使用的docker-compose文件如下,根据docker-compose的内容,大致分为三个部分。
version: '3.7'
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio1:
image: minio/minio:RELEASE.2020-04-15T19-42-18Z
volumes:
- data1-1:/data1
- data1-2:/data2
ports:
- "9001:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio2:
image: minio/minio:RELEASE.2020-04-15T19-42-18Z
volumes:
- data2-1:/data1
- data2-2:/data2
ports:
- "9002:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio3:
image: minio/minio:RELEASE.2020-04-15T19-42-18Z
volumes:
- data3-1:/data1
- data3-2:/data2
ports:
- "9003:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio4:
image: minio/minio:RELEASE.2020-04-15T19-42-18Z
volumes:
- data4-1:/data1
- data4-2:/data2
ports:
- "9004:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
spark-master:
image: cas001/spark-master:2.4.5-hadoop2.7
container_name: cas001-spark-master
ports:
- "7077:7077"
- "8080:8080"
links:
- minio1:S3_db
spark-worker:
image: cas001/spark-worker:2.4.5-hadoop2.7
container_name: cas001-spark-worker
ports:
- "8081"
minio-mc:
image: minio/mc:RELEASE.2020-04-19T19-17-53Z
container_name: cas001-minio-mc
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
links:
- minio1:S3_server
entrypoint: /bin/sh
tty: true
## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
data1-1:
data1-2:
data2-1:
data2-2:
data3-1:
data3-2:
data4-1:
data4-2:
分布式MinIO对象存储服务搭建
分布式MinIO可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式MinIO避免了单点故障。
详细参考这里
Docker-compose中的minio1-4
z组成MinIO分布式存储,对应存储服务的4个节点,每个节点使用相同的MINIO_ACCESS_KEY
和MINIO_SECRET_KEY
。部署成功后访问http://127.0.0.1:9001/,输入minio
,minio123
即可看到如下界面(点击右下角可以创建bucket):
详细参考这里
Spark集群搭建
Docker-compose中的spark-master
,spark-worker
组成Spark集群。spark-master
与minio1
建立容器链接,后续需要Spark读写MinIO存储。部署成功后访问http://127.0.0.1:8080/即可看到如下界面:
Saprk集群相关知识参考这里
MinIO Client搭建
Docker-compose中的minio-mc
对应MinIO Client。MinIO Client提供了一些命令如ls, cat, cp, mirror, diff, find
等,实现与MinIO云存储服务的交互。minio-mc
与minio1
建立容器链接,后续需要使用minio-mc
创建bucket。
MinIO Client的相关知识参考链接1,链接2
启动容器
- 执行
docker-compose up -d
命令,启动所有容器 - 访问http://127.0.0.1:9001/确认MinIO存储服务正常
- 访问http://127.0.0.1:8080/确认Spark集群正常
配置MinIO-Client
- 执行
docker exec -it cas001-minio-mc /bin/sh
进入MinIO-Client - 执行
ping S3_server
确认MinIO存储服务的IP地址,例如192.168.144.3
- 执行以下语句,创建一个名为
spark-test
的bucket,并传入一份test.json
文件
mc config host add myminio http://192.168.144.3:9000 minio minio123
mc mb myminio/spark-test
mc cp test.json myminio/spark-test/test.json
- 执行
mc ls myminio
即可看到创建的bucket
配置Spark集群
Spark访问MinIO存储需要一些依赖包,具体参考这里。其中必须添加的两个jar包是:hadoop-aws-2.7.3,aws-java-sdk-1.7.4。
- Hadoop安装文件夹中包含了上述两个jar包,可以在Hadoop安装目录下执行
find /hadoop_path -name hadoop-aws*.jar
和find /hadoop_path -name hadoop-aws*.jar
来查找jar包的位置。 - 如果本机没有安装Hadoop,即使用的Spark安装包如
spark-2.4.5-bin-hadoop2.7.tgz
所示, 则需要先确认对应的Hadoop具体版本(可以查看spark/jars/
下与Hadoop相关的jar包来确认hadoop版本),然后去下载对应的jar包。 - jar包准备好后,执行
bash copy_dependencies.sh
将对应的jar包拷贝到spark-master
和spark-worker
的spark安装路径jars文件夹下,copy_dependencies.sh
的内容如下:
#!/bin/bash
SPARK_MASTER="cas001-spark-master"
SPARK_WORKER="cas001-spark-worker"
docker cp ./dependencies/. ${SPARK_MASTER}:/spark/jars
docker cp ./dependencies/. ${SPARK_WORKER}:/spark/jars
配置Spark集群参考链接1,链接2,链接3,链接4,链接5
Spark读写MinIO存储
准备工作
- 确保
配置MinIO-Client
执行成功,有对应的bucket
和test.json文件存在
- 执行
docker exec -it cas001-spark-master /bin/bash
进入cas001-spark-master
容器 - 执行
ping S3_db
确认MinIO 存储服务IP地址,例如192.168.144.3
使用spark-shell读取MinIO存储
- 执行如下命令,打开spark-shell
./bin/spark-shell \
--conf spark.hadoop.fs.s3a.endpoint=http://192.168.144.3:9000 \
--conf spark.hadoop.fs.s3a.access.key=minio \
--conf spark.hadoop.fs.s3a.secret.key=minio123 \
--conf spark.hadoop.fs.s3a.path.style.access=true \
--conf spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem
- 执行如下命令读取MinIO存储
val b1 = sc.textFile("s3a://spark-test/test.json")
b1.collect().foreach(println)
-
执行结果如下所示:
参考这里尝试更多的读写操作
注意:spark.hadoop.fs.s3a.endpoint
这项配置后面必须要是ip:端口
的形式,使用docker容器的S3_db:端口
这种方式会报错。
使用spark-submit提交delta-lake作业
- 执行
bash copy-delta-lake-demo.sh
拷贝程序所需的jar包,copy-delta-lake-demo.sh
具体内容如下:
#!/bin/bash
SPARK_MASTER="cas001-spark-master"
docker cp ./delte-lake-demo/. ${SPARK_MASTER}:/spark/examples
- 执行如下命令,提交作业:
./bin/spark-submit --master spark://spark-master:7077 \
--conf spark.delta.logStore.class=org.apache.spark.sql.delta.storage.S3SingleDriverLogStore \
--conf spark.hadoop.fs.s3a.endpoint=http://192.168.144.3:9000 \
--conf spark.hadoop.fs.s3a.access.key=minio \
--conf spark.hadoop.fs.s3a.secret.key=minio123 \
--conf spark.hadoop.fs.s3a.path.style.access=true \
--conf spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem \
--jars /spark/examples/delta-core_2.11-0.5.0.jar \
--class com.delta.Run examples/original-deltaLake2-1.0-SNAPSHOT.jar s3a://spark-test/ delta21 schemaCheck21
# Run 主程序参数:S3_bucket:s3a://spark-test/ ,S3_bucket文件名1:delta21 ,S3_bucket文件名2:schemaCheck21
- 执行结果如下所示:或使用
mc
命令校验