Alluxio集成Amazon AWS S3作为底层存储
该指南介绍配置Amazon S3 作为Alluxio底层文件系统的指令。Alluxio采用s3://
的scheme并且使用aws-sdk访问S3。
初始步骤
首先,本地要有Alluxio二进制包。你可以自己编译Alluxio,或者下载二进制包
另外,为了在S3上使用Alluxio,需要创建一个bucket(或者使用一个已有的bucket)。还要注意在该bucket里使用的目录,可以在该bucket中新建一个目录,或者使用一个存在的目录。在该向导中,S3 bucket的名称为S3_BUCKET
,在该bucket里的目录名称为S3_DIRECTORY
。
挂载S3
Alluxio通过统一命名空间统一对不同存储系统的访问。一个S3位置可以被挂载到Alluxio命名空间的根目录下或者一个嵌套目录中。
根挂载
要使用底层存储系统,你需要编辑conf/alluxio-site.properties
来配置Alluxio。如果该文件不存在,那就从模板创建一个配置文件。
$ cp conf/alluxio-site.properties.template conf/alluxio-site.properties
若要在Alluxio中使用S3作为底层文件系统,一定要修改conf/alluxio-site.properties
配置文件。首先要指定一个已有的S3 bucket和其中的目录作为底层文件系统,可以在conf/alluxio-site.properties
中添加如下语句指定它:
alluxio.master.mount.table.root.ufs=s3n://S3_BUCKET/S3_DIRECTORY
接着,需要指定AWS证书以便访问S3,你可以用不同的方式来指定证书,从最高级到最低级:
优先级
- 被指定为挂载选项的s3a.accessKeyId和s3a.secretKey
- 被指定为Java系统属性的s3a.accessKeyId和s3a.secretKey
- 在Alluxio site属性中的s3a.accessKeyId和s3a.secretKey
- 在Alluxio服务器端的环境变量
AWS_ACCESS_KEY_ID
或AWS_ACCESS_KEY
(都是可接受的)和AWS_SECRET_ACCESS_KEY
或AWS_SECRET_KEY
(都是可接受的) ~/.aws/credentials
目录下包含证书的配置文件- AWS实例配置文件证书,如果你正在使用一个EC2实例
当使用一个AWS实例配置文件作为证书提供者:
- 通过访问被挂载的bucket创建一个IAM Role
- 创建一个Instance profile,作为被定义的IAM Role的容器
- 使用创建好的配置文件启动一个EC2实例
更多详情请参考Amazon的文档。
更改完成后,Alluxio应该能够将S3作为底层文件系统运行,你可以尝试使用S3在本地运行Alluxio。
嵌套挂载
你可以将一个S3位置挂载到Alluxio命名空间中一个嵌套目录中,以便进行统一访问多个底层存储系统。为了达到这一目的,你可以使用Alluxio的 [用户CLI](../operation/User-CLI.html。
$ ./bin/alluxio fs mount \
--option s3a.accessKeyId=<AWS_ACCESS_KEY_ID> \
--option s3a.secretKey=<AWS_SECRET_KEY_ID> \
/mnt/s3 s3://<S3_BUCKET>/<S3_DIRECTORY>
使服务器端加密
你可以加密存储在S3中的数据。加密仅对S3中的数据有效,当客户端读取时,加密将以解密形式传输。
通过配置conf/alluxio-site.properties
来启用此功能:
alluxio.underfs.s3.server.side.encryption.enabled=true
DNS-Buckets
默认情况下,定向到名称为”mybucket”的bucket会被发送到名称为”mybucket.s3.amazonaws.com”的主机。你可以启用DNS-Buckets来使用路径访问数据,例如: 通过设置以下配置来访问”http://s3.amazonaws.com/mybucket”,
alluxio.underfs.s3.disable.dns.buckets=true
通过代理访问S3
若要通过代理与S3交互,修改文件conf/alluxio-site.properties
以包含:
alluxio.underfs.s3.proxy.host=<PROXY_HOST>
alluxio.underfs.s3.proxy.port=<PROXY_PORT>
其中,<PROXY_HOST>
和<PROXY_PORT>
为代理的主机名和端口。
配置应用依赖
当使用Alluxio构建你的应用时,你的应用需要包含一个client模块,如果要使用Alluxio file system interface,那么需要配置alluxio-core-client-fs
模块,如果需要使用Hadoop file system interface,则需要使用alluxio-core-client-hdfs
模块。
举例来说,如果你正在使用 maven,你可以通过添加以下代码来添加你的应用的依赖:
<!-- Alluxio file system interface -->
<dependency>
<groupId>org.alluxio</groupId>
<artifactId>alluxio-core-client-fs</artifactId>
<version>2.10.0-SNAPSHOT</version>
</dependency>
<!-- HDFS file system interface -->
<dependency>
<groupId>org.alluxio</groupId>
<artifactId>alluxio-core-client-hdfs</artifactId>
<version>2.10.0-SNAPSHOT</version>
</dependency>
另外,你也可以将conf/alluxio-site.properties
(包含了设置证书的配置项)拷贝到你的应用运行时的classpath中(例如对于Spark而言为$SPARK_CLASSPATH
),或者将该配置文件所在的路径追加到classpath末尾。
使用非亚马逊服务提供商
如果需要使用一个不是来自”s3.amazonaws.com”的S3服务,修改文件conf/alluxio-site.properties
以包含:
alluxio.underfs.s3.endpoint=<S3_ENDPOINT>
对于这些参数,将<S3_ENDPOINT>
参数替换成你的S3服务的主机名和端口,例如http://localhost:9000
。该参数只有在你的服务提供商非s3.amazonaws.com
时才需要进行配置。
使用v2的S3签名
一些S3服务提供商仅仅支持v2签名。对这些S3提供商来说,可以通过设置alluxio.underfs.s3.signer.algorithm
为S3SignerType
来强制使用v2签名。
使用S3在本地运行Alluxio
配置完成后,你可以在本地启动Alluxio,观察一切是否正常运行:
$ ./bin/alluxio format
$ ./bin/alluxio-start.sh local
该命令应当会启动一个Alluxio master和一个Alluxio worker,可以在浏览器中访问http://localhost:19999查看master Web UI。
接着,你可以运行一个简单的示例程序:
$ ./bin/alluxio runTests
运行成功后,访问你的S3目录S3_BUCKET/S3_DIRECTORY
,确认其中包含了由Alluxio创建的文件和目录。在该测试中,创建的文件名称应像下面这样:
S3_BUCKET/S3_DIRECTORY/alluxio/data/default_tests_files/Basic_CACHE_THROUGH
运行以下命令停止Alluxio:
$ ./bin/alluxio-stop.sh local
S3访问控制
如果Alluxio安全认证被启用,Alluxio将会遵循底层对象存储的访问权限控制。
Alluxio配置中指定的S3证书代表一个S3用户,S3服务终端在一个用户访问bucket和对象时将会检查该用户的权限,如果该用户对某个bucket没有足够的访问权限,将会抛出一个权限错误。当Alluxio安全认证被启用时,Alluxio在第一次从底层S3将元数据加载到Alluxio命名空间时便会同时将其bucket的ACL也加载到Alluxio访问权限元数据中。
S3用户到Alluxio文件所有者的映射关系
默认情况下,Alluxio会尝试从S3证书中解析其S3用户名。另外,也可以配置alluxio.underfs.s3.owner.id.to.username.mapping
从而指定某个S3编号到Alluxio用户名的映射关系,其配置形式为”id1=user1;id2=user2”。AWS S3规范编号可以在该控制台地址找到,请展开Account Identifiers
选项卡,并参考”Canonical User ID”。
S3 ACL到Alluxio权限的映射关系
Alluxio通过S3 bucket的读写ACL来决定Alluxio文件的所有者权限模式。举例来说,如果一个S3用户对某个底层S3 bucket具有只读权限,那么该挂载的目录以及文件的权限模式为0500,如果该S3用户具有所有权限,那么其Alluxio权限模式将为0700。
挂载点共享
如果你想在Alluxio命名空间中与其他用户共享S3挂载点,可以启用alluxio.underfs.object.store.mount.shared.publicly
。
权限更改
对Alluxio目录或者文件进行chown
, chgrp
, chmod
操作不会对其底层S3 bucket或者对象的权限做出更改。
文件权限
Alluxio通过检查S3存储桶的读/写ACL来确定文件所有者对Alluxio文件的权限。
例如,如果AWS用户对已挂载的存储桶具有只读访问权限,则已挂载的存储桶
目录和文件将设置为0500
权限。
如果AWS用户对底层存储桶具有完全访问权限,
挂载的目录和文件将设置为0700
权限。
注意,Alluxio仅在确定挂载点的文件系统权限时继承存储桶级ACL,
并忽略单个对象的ACLS设置。
0500
或0700
为文件默认权限,非文件所有者Alluxio文件系统用户将
无法访问该挂载点下的文件。
这可能给不同的用户读取挂载的数据带来问题。
例如,在用户presto
下运行的Presto作业可能会遇到类似以下错误
当访问权限为0700的用户john拥有的挂载点时出现错误 Query failed: Failed to list directory。
在Alluxio master日志(master.log
)中,可以找到类似以下错误
Error=alluxio.exception.AccessControlException: Permission denied: user=presto, access=--x, path=/mnt/s3/myobject: failed at s3, inode owner=john, inode group=john, inode mode=rwx------
这是因为挂载的目录具有0700
权限,因此应用程序用户presto
无法访问该文件。
要与Alluxio命名空间中的其他用户共享S3挂载点,可以选择以下两者之一:
1.(选项1):为根挂载设置
alluxio-site.properties
中的alluxio.master.mount.table.root.shared=true
或
在fs mount命令中传递–shared参数; 如此设置给所有用户rwx
权限。
2.(选项2):将alluxio.underfs.s3.inherit.acl=false
和alluxio.underfs.s3.default.mode
设置为一个新的非0700
默认值,来允许其他用户访问。
更改权限
针对Alluxio目录和文件的chown
,chgrp
和chmod
等权限更改命令不会修改底层
S3桶或对象的权限。
故障排除
启用AWS-SDK Debug级别
如果在特定S3后端上运行时遇到问题,请启用额外日志记录以跟踪HTTP网流。 修改conf/log4j.properties
以添加以下属性:
log4j.logger.com.amazonaws=WARN
log4j.logger.com.amazonaws.request=DEBUG
log4j.logger.org.apache.http.wire=DEBUG
更多细节请参阅Amazon文档。
防止创建零字节文件
Alluxio为优化性能会在S3中创建零字节文件。
对于挂载的有读写访问权限的存储桶,零字节文件创建(S3 PUT操作)
不仅限于用Alluxio进行写入会发生,还会在列出底层存储内容时发生。
要禁用PUT操作,在挂载桶时用--readonly
标记或为根挂载设置alluxio.master.mount.table.root.readonly=true
。