本文简要介绍了在Hadoop集群(包括Hadoop、Hive与Spark)中使用S3(对象存储)文件系统的方法与注意事项。
对象存储
S3(Simple Storage Service)是一种对象存储服务,具有可扩展性、数据可用性、安全性和性能等优势。S3兼容存储是一种存储解决方案,允许用户访问和管理它通过S3兼容接口存储的数据。
现有的主流S3存储服务:
Hadoop 配置步骤
依赖包位置
Hadoop自带S3依赖,位置如下:
1 2
| $HADOOP_HOME/share/hadoop/tools/lib/hadoop-aws-3.1.3.jar $HADOOP_HOME/share/hadoop/tools/lib/aws-java-sdk-bundle-1.11.271.jar
|
但是这些依赖包默认不在hadoop classpath
下面。可以使用以下两种方法引入这两个包:
- 在
hadoop-env.sh
中加入export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/share/hadoop/tools/lib/*
。更改完毕后可以使用hadoop classpath
确定。
- 通过软链接:
ln -s $HADOOP_HOME/share/hadoop/tools/lib/*aws* $HADOOP_HOME/share/hadoop/common/lib/
注意,Minio可能会出现hdfs dfs -ls
空文件夹报错的情况,也有可能可以正常部署但是无法通过YARN提交任务。遇到这种情况可以考虑降低aws-java-sdk-bundle
的版本为1.11.84
,然后重启集群。经测试,Hadoop 3.1.3与3.2.0两个版本可以与aws-java-sdk-bundle-1.11.84
兼容,Hadoop 3.3.x版本暂时无法兼容。更换aws-java-sdk-bundle
包版本后需要分发到所有集群。
配置 core-site.xml
在$HADOOP_HOME/etc/hadoop/core-site.xml
加入如下内容(分发至所有机器):
core-site.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>fs.s3a.access.key</name> <value>[ak]</value> </property> <property> <name>fs.s3a.secret.key</name> <value>[sk]</value> </property> <property> <name>fs.s3a.connection.ssl.enabled</name> <value>false</value> </property> <property> <name>fs.s3a.path.style.access</name> <value>true</value> </property> <property> <name>fs.s3a.endpoint</name> <value>http://[endpoint]</value> </property> <property> <name>fs.s3a.impl</name> <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value> </property> </configuration>
|
更改完毕并重启集群后,可以使用hdfs dfs -ls s3a://[bucket]/
等命令操作S3中的文件。
注意,若想将默认文件系统改为S3,需要配置fs.defaultFS
为S3中的一个存储桶。示例如下:
core-site.xml1 2 3 4
| <property> <name>fs.defaultFS</name> <value>s3a://[default-bucket]/</value> </property>
|
注意,使用Ceph部署时,会出现hdfs dfs -ls
出现listStatus
报错的情况,该报错会显示com.amazonaws.services.s3.model.AmazonS3Exception: Invalid Argument
。这是因为Ceph最多只能支持max-keys
为1000,但在core-default.xml
里该默认设置为5000。需要增加如下配置来解决:
core-site.xml1 2 3 4
| <property> <name>fs.s3a.paging.maximum</name> <value>1000</value> </property>
|
创建S3存储桶
有些S3实现自带UI,对S3存储桶与文件的操作可以直接在UI上完成。也可以使用S3 Browser(仅限Windows)或者Rclone、s3cmd等命令行工具。这里简要演示s3cmd
的使用方法:
1 2 3
| yum install -y s3cmd vim ~/.s3cfg s3cmd mb s3://[some-bucket]
|
其中 ~/.s3cfg
的内容如下(根据自己的情况配置):
1 2 3 4 5 6 7 8 9
| host_base = [endpoint] host_bucket = [endpoint] bucket_location = us-east-1 use_https = False
access_key = [ak] secret_key = [sk]
signature_v2 = False
|
其他配置
至此,已经可以使用HDFS Client查看和获取到S3的文件了。如需使用YARN和MapReduce,可以尝试增加如下配置:
hdfs-site.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>dfs.namenode.datanode.registration.ip-hostname-check</name> <value>false</value> </property><property> <name>dfs.permissions.enabled</name> <value>false</value> </property> <property> <name>dfs.namenode.rpc-bind-host</name> <value>0.0.0.0</value> </property> <property> <name>dfs.namenode.servicerpc-bind-host</name> <value>0.0.0.0</value> </property> <property> <name>dfs.namenode.http-bind-host</name> <value>0.0.0.0</value> </property> <property> <name>dfs.namenode.https-bind-host</name> <value>0.0.0.0</value> </property> <property> <name>dfs.client.use.datanode.hostname</name> <value>false</value> </property> <property> <name>dfs.datanode.use.datanode.hostname</name> <value>false</value> </property> </configuration>
|
需要将下面yarn-site.xml
里的yarn.resourcemanager.hostname
改为对应ResourceManager的地址:
yarn-site.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>[yarn-rm-hostname]</value> </property> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore</value> </property> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <property> <name>mapred.map.output.compress.codec</name> <value>org.apache.hadoop.io.compress.SnappyCodec</value> </property> <property> <name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value> </property> <property> <name>mapreduce.map.output.compress</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> </property> <property> <name>yarn.resourcemanager.bind-host</name> <value>0.0.0.0</value> </property> <property> <name>yarn.nodemanager.bind-host</name> <value>0.0.0.0</value> </property> <property> <name>yarn.nodemanager.bind-host</name> <value>0.0.0.0</value> </property> <property> <name>yarn.timeline-service.bind-host</name> <value>0.0.0.0</value> </property> <property> <name>yarn.application.classpath</name> <value> /usr/local/hadoop/etc/hadoop, /usr/local/hadoop/share/hadoop/common/*, /usr/local/hadoop/share/hadoop/common/lib/*, /usr/local/hadoop/share/hadoop/hdfs/*, /usr/local/hadoop/share/hadoop/hdfs/lib/*, /usr/local/hadoop/share/hadoop/mapreduce/*, /usr/local/hadoop/share/hadoop/mapreduce/lib/*, /usr/local/hadoop/share/hadoop/yarn/*, /usr/local/hadoop/share/hadoop/yarn/lib/* </value> </property> </configuration>
|
mapred-site.xml1 2 3 4 5 6 7 8
| <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
|
配置完毕后,需要重启整个Hadoop集群。
Hive 配置步骤
依赖包配置
在Hive的安装目录下进行以下操作,增加依赖包:
1 2
| mkdir $HIVE_HOME/auxlib ln -s $HADOOP_HOME/share/hadoop/tools/lib/*aws* $HIVE_HOME/auxlib/
|
创建core-site.xml
在$HIVE_HOME/conf
目录下新建core-site.xml
并加入如下配置:
core-site.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <configuration> <property> <name>fs.defaultFS</name> <value>s3a://[default-bucket]</value> </property> <property> <name>fs.s3a.access.key</name> <value>[ak]</value> </property> <property> <name>fs.s3a.secret.key</name> <value>[sk]</value> </property> <property> <name>fs.s3a.connection.ssl.enabled</name> <value>false</value> </property> <property> <name>fs.s3a.path.style.access</name> <value>true</value> </property> <property> <name>fs.s3a.endpoint</name> <value>http://[endpoint]</value> </property> <property> <name>fs.s3a.impl</name> <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value> </property> </configuration>
|
其中fs.defaultFS
这一项依据$HADOOP_HOME/etc/hadoop/core-site.xml
是否配置此项而定。
配置hive-env.sh
在$HIVE_HOME/conf
目录下运行cp hive-env.sh.template hive-env.sh
后添加如下内容:
hive-env.sh1 2
| export HIVE_AUX_JARS_PATH=$HIVE_HOME/auxlib
|
重启Hive服务
1
| $HIVE_HOME/bin/hiveservices.sh restart
|
Spark 配置步骤
运行以下语句并分发至所有机器,随后重启Spark Standalone集群:
1 2 3
| wget https://repo1.maven.org/maven2/com/google/guava/guava/27.0-jre/guava-27.0-jre.jar -P $SPARK_HOME/jars ln -s $HADOOP_HOME/share/hadoop/tools/lib/*aws* $SPARK_HOME/jars/ mv $SPARK_HOME/jars/guava-14.0.1.jar $SPARK_HOME/jars/guava-14.0.1.jar.bak
|
如果将是将Spark的任务提交到YARN,则需要在spark-env.sh
里配置YARN_CONF_DIR
:
spark-env.sh1
| YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop
|