

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon EFS 性能提示
<a name="performance-tips"></a>

在使用 Amazon EFS 时，请记住以下性能提示。

## 平均 I/O 大小
<a name="efs-perf-avg-io-size"></a>

Amazon EFS 的分布式特性实现了高水平的可用性、持久性和可扩展性。这种分布式架构使得每次文件操作只产生很小的延迟开销。由于每次操作都有这种延迟，因此总体吞吐量通常会随着平均 I/O 大小的增加而增加，因为开销会分摊到较大的数据量上。

## 优化需要高吞吐量和 IOPS 的工作负载
<a name="recs-intensive-workloads"></a>

对于需要高吞吐量和 IOPS 的工作负载，请使用配置了通用性能模式和弹性吞吐量的区域性文件系统。

**注意**  
要对频繁访问的数据实现最大次读取 IOPS，文件系统必须使用弹性吞吐量。

要实现最高级别的性能，必须通过按如下方式配置应用程序或工作负载来利用并行化。

1. 在所有客户端和目录之间均匀分配工作负载，目录数至少与使用的客户端数量相同。

1. 通过将各个线程与不同的数据集或文件对齐，最大限度地减少争用。

1. 将工作负载分配到 10 个或更多的 NFS 客户端，单个装载目标中每个客户端至少有 64 个线程。

## 同时连接
<a name="efs-perf-sim-connections"></a>

您可以同时在多达数千个 Amazon EC2 和其他 Amazon 计算实例上挂载 Amazon EFS 文件系统。如果可以跨更多实例并行执行应用程序，则可以在跨计算实例的聚合中提高文件系统的吞吐量级别。

## 请求模型
<a name="efs-perf-request-model"></a>

如果启用对文件系统的异步写入，则待处理的写入操作会在 Amazon EC2 实例上缓冲，然后再异步写入 Amazon EFS。异步写入通常具有较低的延迟。在执行异步写入时，内核使用额外内存进行缓存。

启用了同步写入的文件系统或使用绕开缓存选项（例如 `O_DIRECT`）打开文件的文件系统将向 Amazon EFS 发出同步请求。每个操作都将在客户端和 Amazon EFS 之间往返一次。

**注意**  
您选择的请求模型将在一致性（如果您使用多个 Amazon EC2 实例）和速率之间进行取舍。使用同步写入可以在处理下一个请求之前完成每个写入请求事务，从而提高数据一致性。使用异步写入可通过缓冲待处理的写入操作来提高吞吐量。

## NFS 客户端挂载设置
<a name="efs-perf-nfs-client-mnt-settings"></a>

确认您使用的是 [挂载 EFS 文件系统](mounting-fs.md) 和 [Linux 的挂载注意事项](mounting-fs-mount-cmd-general.md) 中推荐的挂载选项。

在 Amazon EC2 实例上挂载文件系统时，Amazon EFS 支持网络文件系统版本 4.0 和 4.1（NFSv4）协议。与 NFSv4.0（每秒少于 1 千个文件）相比，NFSv4.1 为并行小文件读取操作提供了更高的性能（每秒大于 1 万个文件）。对于运行 macOS Big Sur 的亚马逊 EC2 macOS 实例，仅 NFSv4支持 .0。

请勿使用以下挂载选项：
+ `noac`、`actimeo=0`、`acregmax=0`、`acdirmax=0` – 这些选项会禁用属性缓存，这会对性能产生非常大的影响。
+ `lookupcache=pos`、`lookupcache=none` – 这些选项会禁用文件名查找缓存，这会对性能产生非常大的影响。
+ `fsc` – 此选项启用本地文件缓存，但不会更改 NFS 缓存的一致性，也不会减少延迟。

**注意**  
在挂载文件系统时，请考虑将 NFS 客户端的读写缓冲区大小增加到 1 MB。

## 优化小文件性能
<a name="optimize-open-close"></a>

可以通过最大限度地减少文件重新打开次数、增加并行度，以及尽可能捆绑参考文件来提高小文件的性能。
+ 尽量减少往返服务器的次数。

  如果以后在工作流中需要文件，请不要不必要地关闭这些文件。保持文件描述符处于打开状态可以直接访问缓存中的本地副本。文件打开、关闭和元数据操作通常不能以异步方式或通过管道进行。

  读取或写入小文件时，两次额外往返非常重要。

  每次往返（文件打开、文件关闭）所花费的时间可能与读取或写入兆字节批量数据一样多。在计算作业开始时打开一次输入或输出文件，并在整个作业期间保持打开状态会更有效。
+ 使用并行度来减少往返时间的影响。
+ 将参考文件捆绑到 `.zip` 文件中。有些应用程序使用大量较小的主要是只读文件的参考文件。将这些文件捆绑到一个 `.zip` 文件中，只需一次打开-关闭往返操作即可读取多个文件。

  `.zip` 格式允许随机访问单个文件。

## 优化目录性能
<a name="optimize-directories"></a>

在同时修改的超大目录（超过 10 万个文件）上执行列出操作（**ls**）时，Linux NFS 客户端可能会挂起而不返回响应。此问题已在内核 5.11 中修复，该内核已移植到 Amazon Linux 2 内核 4.14、5.4 和 5.10。

我们建议您在可能的情况下，将文件系统上的目录数保持在 1 万以内。尽可能多地使用嵌套子目录。

列出目录时，如果不需要文件属性，应避免获取这些属性，因为它们并未存储在目录本身中。

## 优化 NFS read\_ahead\_kb 的大小
<a name="efs-perf-optimize-nfs-read-ahead"></a>

NFS `read_ahead_kb` 属性定义了 Linux 内核在顺序读取操作期间要提前读取或预取的千字节数。

对于 5.4.\* 之前的 Linux 内核版本，`read_ahead_kb` 值是通过 `NFS_MAX_READAHEAD` 乘以 `rsize`（挂载选项中设置的客户端配置的读取缓冲区大小）的值来设置的。使用[推荐的挂载选项](mounting-fs-mount-cmd-general.md)时，此公式将 `read_ahead_kb` 设置为 15 MB。

**注意**  
从 Linux 内核版本 5.4.\* 开始，Linux NFS 客户端使用默认 `read_ahead_kb` 值 128 KB。我们建议将此值增加到 15 MB。

挂载文件系统后，`amazon-efs-utils` 版本 1.33.2 及更高版本中提供的 Amazon EFS 挂载帮助程序会自动将 `read_ahead_kb` 值修改为等于 15 \* `rsize` 或 15 MB。

对于 Linux 内核 5.4 或更高版本，如果不使用挂载帮助程序来挂载文件系统，请考虑手动将 `read_ahead_kb` 设置为 15 MB 以提高性能。挂载文件系统后，可使用以下命令重置 `read_ahead_kb` 值。在使用此命令之前，替换以下值：
+ 将 `{{read-ahead-value-kb}}` 替换为所需的大小（以千字节为单位）。
+ 将 `{{efs-mount-point}}` 替换为文件系统的挂载点。

```
device_number=$(stat -c '%d' {{efs-mount-point}})
((major = ($device_number & 0xFFF00) >> 8))
((minor = ($device_number & 0xFF) | (($device_number >> 12) & 0xFFF00)))
sudo bash -c "echo {{read-ahead-value-kb}} > /sys/class/bdi/$major:$minor/read_ahead_kb"
```

以下示例将 `read_ahead_kb` 大小设置为 15 MB。

```
device_number=$(stat -c '%d' efs)
((major = ($device_number & 0xFFF00) >> 8))
((minor = ($device_number & 0xFF) | (($device_number >> 12) & 0xFFF00)))
sudo bash -c "echo 15000 > /sys/class/bdi/$major:$minor/read_ahead_kb"
```