1. 背景

https://blog.51cto.com/u_15327484/8193991介绍了海外Hadoop集群一般将冷数据放入到AWS S3或者存放到Google gcs对象存储中。这些对象存储都提供了各自的客户端进行访问,例如aws s3的客户端命令就是aws s3;gcs的客户端命令是gsutil。这些命令一般需要直接登陆到授权机器中执行,比较麻烦。

为了解决这个问题,AWS S3和Google gcs都提供了对应的SDK给Hadoop进行集成,通过指定对应的文件系统类,可以通过sdk访问s3和gcs。

2. hadoop整合aws s3对象存储

下载aws的SDK文件:hadoop-aws-x.x.x.jar,aws-java-sdk-bundle-x.x.x.jar,放到hadoop的安装目录hadoop/share/hadoop/common下。

在core-site.xml增加如下配置:

<property>
  <name>fs.s3a.access.key</name>
  <description>AWS access key ID.
   Omit for IAM role-based or provider-based authentication.</description>
  <value>xxxxxx</value>
</property>

<property>
  <name>fs.s3a.secret.key</name>
  <description>AWS secret key.
   Omit for IAM role-based or provider-based authentication.</description>
  <value>xxxxxx</value>
</property>

<property>
  <name>fs.s3a.aws.credentials.provider</name>
  <value>org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider</value>
</property>

注意,fs.s3a.aws.credentials.provider可以有多种配置:

  1. com.amazonaws.auth.EnvironmentVariableCredentialsProvider:使用环境变量AWS_ACCESS_KEY_ID 和AWS_SECRET_ACCESS_KEY。
  2. com.amazonaws.auth.InstanceProfileCredentialsProvider: 使用profile。
  3. org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider: 使用fs.s3a.access.key and fs.s3a.secret.key 配置项。一般都是用这种方式。

如果想通过credentials文件的方式访问,就在hdfs中创建credential文件:

hadoop credential create fs.s3a.access.key -value xxxxx -provider jceks://hdfs@cluster1/user/s3key/credential.jceks 
hadoop credential create fs.s3a.secret.key -value xxxxx -provider jceks://hdfs@cluster1/user/s3key/credential.jceks

方法方式:

hadoop fs -D hadoop.security.credential.provider.path=jceks://hdfs@cluster1/user/s3key/credential.jceks -ls s3a://bucket/

3. hadopo整合google gcs对象存储

下载gcs的SDK文件:gcs-connector-hadoop3-latest.jar,放到hadoop的安装目录hadoop/share/hadoop/common下。

在core-site.xml增加如下配置:

<property>
  <name>fs.AbstractFileSystem.gs.impl</name>
  <value>com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS</value>
  <description>The AbstractFileSystem for 'gs:' URIs.</description>
</property>

这样就搭建好了基础的使用姿势。如果gcs开启了aksk认证,需要将aksk转化为credential写到hdfs中,在访问时指定credential即可完成认证:

hadoop credential create fs.gs.auth.service.account.email  \
  -provider jceks://hdfs/app/client-app-a/sa-data-access-a.jceks \
  -value "具体email"
hadoop credential create fs.gs.auth.service.account.private.key.id \
  -provider jceks://hdfs/app/client-app-a/sa-data-access-a.jceks \
  -value "ak"
hadoop credential create fs.gs.auth.service.account.private.key \
  -provider jceks://hdfs/app/client-app-a/sa-data-access-a.jceks \
  -value "sk"

如下,指定credential,即可完成认证并访问gcs:

hadoop dfs  -Dhadoop.security.credential.provider.path=jceks://hdfs@cluster/user/yuliang02/test/gdc-data-tianma.jceks  -ls  gs://gdc-data-tianma-sa/test/test_gcs_distcp_file

4. aws s3智能分层支持

4.1 aws s3智能分层介绍

AWS对S3有以下三种经常存储策略:

  • Standard:通用策略。
  • Standard-IA:不频繁访问策略,必须手动设置S3对象为不频繁访问,设置之后对象无法自动升级和降级。
  • Intelligent - Tiering:智能分层策略,根据数据冷热程度自动对存储进行升级和降级。

AWS S3智能分层策略流程:

  1. 初次上传文件到s3后,会存储在频繁访问层。
  2. 对于频繁访问层大于128KB的文件,如果超过30天没访问,就转移到不频繁访问层。
  3. 对于不频繁访问层的文件,如果超过90天没有访问,就转移到归档即时访问层。
  4. 对于归档即时访问层,如果手动设置N天移动归档访问层,经过N天会移动到归档访问层。
  5. 对于归档即时访问层,如果没有设置移动归档访问层,超过180天移动到深度存储归档层。
  6. 对于归档访问层,由于设置了存储时间上限,超过时间上限,会移动到深度存储归档层。
  7. 对于所有非频繁访问层的文件,一旦用户再次访问S3对象,就会将S3对象转化为频繁访问层。
  8. 不频繁访问层转化为频繁访问层,需要?时间(理论上切换不需要时间)。
  9. 归档即时访问层转化为频繁访问层,需要?时间(理论上切换不需要时间)。
  10. 归档访问层转化为频繁访问层,最长需要5h。
  11. 深度存储归档层转化为频繁访问层,最长需要12h。

其流程图如下所示:

Untitled.png

经过统计,总共2000TB的S3数据,最终大约会有1996.43TB落到不频繁访问层,最终每月能节省4779.03刀的存储费用。

HDFS默认情况下没有指定对象的存储策略,那么文件存储时就是通用策略。只有当设置了桶的存储策略后一段时间内才会将对象转变为Intelligent - Tiering类型。因此,可以引入https://issues.apache.org/jira/browse/HADOOP-12020,在s3a客户端指定对象的存储策略为Intelligent - Tiering类型。可以有效降低存储成本。其关键代码如下:

Untitled 1.png

客户端上传文件到S3时,在HDFS-site.xml中新增存储类型:

Untitled 2.png 上传到S3后,发现对象的存储类型就是智能分层类型:

Untitled 3.png

5. 智能分层相关业务适配

S3的整体存储信息来自于S3的inventory生成的文件,一般会建立一张hive表用于查询inventory信息。开启了智能分层后,inventory新增了智能分层字段,为了获取S3中每个对象的存储层次,需要在hive表中增加相应字段:

如下,在hive表中增加对象的存储类型和目前所处的层次字段:

Untitled 4.png