> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/os-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.alluxio.io/os-cn/ufs/s3.md).

# Alluxio集成Amazon AWS S3作为底层存储

该指南介绍配置[Amazon S3](https://aws.amazon.com/s3/) 作为Alluxio底层文件系统的指令。Alluxio采用`s3://`的scheme并且使用aws-sdk访问S3。

## 初始步骤

首先，本地要有Alluxio二进制包。你可以自己[编译Alluxio](/os-cn/contributor/building-alluxio-from-source.md)，或者[下载二进制包](/os-cn/deploy/running-alluxio-locally.md)

另外，为了在S3上使用Alluxio，需要创建一个bucket（或者使用一个已有的bucket）。还要注意在该bucket里使用的目录，可以在该bucket中新建一个目录，或者使用一个存在的目录。在该向导中，S3 bucket的名称为`S3_BUCKET`，在该bucket里的目录名称为`S3_DIRECTORY`。

## 挂载S3

Alluxio通过统一命名空间统一对不同存储系统的访问。一个S3位置可以被挂载到Alluxio命名空间的根目录下或者一个嵌套目录中。

### 根挂载

要使用底层存储系统，你需要编辑`conf/alluxio-site.properties`来配置Alluxio。如果该文件不存在，那就从模板创建一个配置文件。

```console
$ cp conf/alluxio-site.properties.template conf/alluxio-site.properties
```

若要在Alluxio中使用S3作为底层文件系统，一定要修改`conf/alluxio-site.properties`配置文件。首先要指定一个**已有的**S3 bucket和其中的目录作为底层文件系统，可以在`conf/alluxio-site.properties`中添加如下语句指定它：

```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](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)
* 创建一个[Instance profile](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#ec2-instance-profile)，作为被定义的IAM Role的容器
* 使用创建好的配置文件启动一个EC2实例

更多详情请参考[Amazon的文档](https://docs/aws.amazon.com/java-sdk/latest/developer-guide/credentials/html#id6)。

更改完成后，Alluxio应该能够将S3作为底层文件系统运行，你可以尝试[使用S3在本地运行Alluxio](#running-alluxio-locally-with-s3)。

### 嵌套挂载

你可以将一个S3位置挂载到Alluxio命名空间中一个嵌套目录中，以便进行统一访问多个底层存储系统。为了达到这一目的，你可以使用Alluxio的 [用户CLI](/os-cn/operation/user-cli.md)。

```console
$ ./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`以包含：

```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](https://github.com/Alluxio/documentation/blob/main/docs/cn/ufs/File-System-API.html)，那么需要配置`alluxio-core-client-fs`模块，如果需要使用[Hadoop file system interface](https://wiki.apache.org/hadoop/HCFS)，则需要使用`alluxio-core-client-hdfs`模块。 举例来说，如果你正在使用 [maven](https://maven.apache.org/)，你可以通过添加以下代码来添加你的应用的依赖：

```xml
<!-- Alluxio file system interface -->
<dependency>
  <groupId>org.alluxio</groupId>
  <artifactId>alluxio-core-client-fs</artifactId>
  <version>2.9.5</version>
</dependency>
<!-- HDFS file system interface -->
<dependency>
  <groupId>org.alluxio</groupId>
  <artifactId>alluxio-core-client-hdfs</artifactId>
  <version>2.9.5</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，观察一切是否正常运行：

```console
$ ./bin/alluxio format
$ ./bin/alluxio-start.sh local
```

该命令应当会启动一个Alluxio master和一个Alluxio worker，可以在浏览器中访问<http://localhost:19999>查看master Web UI。

接着，你可以运行一个简单的示例程序：

```console
$ ./bin/alluxio runTests
```

运行成功后，访问你的S3目录`S3_BUCKET/S3_DIRECTORY`，确认其中包含了由Alluxio创建的文件和目录。在该测试中，创建的文件名称应像下面这样：

```
S3_BUCKET/S3_DIRECTORY/alluxio/data/default_tests_files/Basic_CACHE_THROUGH
```

运行以下命令停止Alluxio：

```console
$ ./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规范编号可以在[该控制台地址](https://console.aws.amazon.com/iam/home?#security_credential)找到，请展开`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`以添加以下属性:

```properties
log4j.logger.com.amazonaws=WARN
log4j.logger.com.amazonaws.request=DEBUG
log4j.logger.org.apache.http.wire=DEBUG
```

更多细节请参阅[Amazon文档](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-logging.html)。

### 防止创建零字节文件

Alluxio为优化性能会在S3中创建零字节文件。 对于挂载的有读写访问权限的存储桶，零字节文件创建(S3 PUT操作) 不仅限于用Alluxio进行写入会发生，还会在列出底层存储内容时发生。 要禁用PUT操作，在挂载桶时用`--readonly` 标记或为根挂载设置`alluxio.master.mount.table.root.readonly=true`。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://documentation.alluxio.io/os-cn/ufs/s3.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
