spark对接aws s3以及兼容s3接口的对象存储

       之前写了一篇如何让spark使用阿里云oss对象存储替代本地存储或者hdfs存储jar包,日志等,文章链接:spark对接oss对象存储

       今天写一篇比较通用的,即spark对接aws s3或者其他厂商兼容s3接口的对象存储。

环境

spark环境:

spark-3.1.3-bin-hadoop3.2

hadoop源码:

hadoop3.2

添加jar包

       我使用的是spark-3.1.3-bin-hadoop3.2这个spark环境。默认的版本中是没有s3的相关jar包的,因此只能使用hdfs或者local。

       在hadoop源码中(https://github.com/apache/hadoop),有一个hadoop-tools文件夹,下面放着的都是hadoop周边衍生工具代码,比如hadoop-aliyun是hadoop对接aliyun的,再比如hadoop-aws是hadoop对接aws的。

       我们通过编译hadoop代码,可以在hadoop-aws/target下面得到hadoop-aws-3.2.0.jar,这个jar包还依赖aws-java-sdk-bundle-1.11.375.jar,这个jar包在hadoop-aws/target/lib下面。将这两个jar包,放到spark-3.1.3-bin-hadoop3.2/jars下面。

       因为我是基于k8s提交spark作业,所以将spark-3.1.3-bin-hadoop3.2打成docker镜像。

修改配置

连接s3

       放置完jar后,还需要添加一下配置才能使用。

       进入spark-3.1.3-bin-hadoop3.2/conf文件夹,执行命令

vi spark-defaults.conf

        在打开的文件中添加如下配置:

spark.hadoop.fs.s3a.access.key=6GDA3TY024S4ONGZO3IE
spark.hadoop.fs.s3a.secret.key=uBiJjhSPqwhPN8Oq5N8bO6cJWMC9rA0He7ripc7C
spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem
spark.hadoop.fs.s3a.endpoint=s3.us-east-2.amazonaws.com

        将ak, sk, endpoint改成你自己的。这样就可以用了。

打开日志功能

        如果想要将日志也放到oss中,还需要加上两行配置。

spark.eventLog.enabled true
spark.eventLog.dir s3a://

 historyserver的配置

         如果想通过historyserver,读取oss中的日志,则需要改另一个文件,执行命令

vi spark-env.sh

       在里面加入如下配置

export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.retainedApplications=10 -Dspark.history.fs.logDirectory=s3a:// -Dspark.history.fs.update.interval=10"

如何使用其他厂商的云

       目前hadoop中只有阿里云和aws s3的连接工具,如果你想使用的厂商和不完全兼容s3(使用s3的sdk,无法操作该厂商的对象存储),则需要自己开发hadoop工具。如果是完全兼容s3的,比如移动云EOS,只是名字和s3不一样,但api完全兼容,则可以直接复用hadoop-aws,但是需要改一下hadoop-common的代码,否则不能识别类似eos://的前缀。

       修改代码的方式如下:

       在hadoop源码的根目录,执行下面的命令,打开代码:

vi hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java

        找到getFileSystemClass这个函数。该函数会根据传入的前缀判断一下是否有对应的类,如果没有就会报找不到类的错误。因此可以改一下代码:

if (!scheme.equals("oss") || !scheme.equals("s3a")){
       scheme = "s3a";
}

      这样其他厂家的前缀都会在该函数内被转成s3a,这样便可以找到s3a这个类,使用后面的api方法了。

你可能感兴趣的:(spark,spark,aws,大数据)