> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/ee-ai-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/ee-ai-cn/performance/metadata-listing.md).

# 元数据优化

索引服务是用于目录列表的缓存服务，旨在处理包含数亿个文件和子目录的大型目录，同时提供高性能和可扩展性。

## 概述

索引服务是目录列表的分布式缓存，类似于常规文件的元数据和数据缓存。它利用缓存内容提供比直接列出UFS更快的列表。在客户端，它支持并行处理目录条目，以提高列表操作的性能。

索引服务还与[缓存过滤器](https://documentation.alluxio.io/ee-ai-cn/performance/pages/YDY8IXmveHXAHBwQ8zU3#控制缓存内容缓存过滤策略)集成，以支持为不同目录设置细粒度的缓存过滤器规则。

索引服务最适合 **UFS 内容变更不频繁的稳定或只读数据集**。如果命名空间中包含可变目录，则必须为这些目录配置对应的缓存过滤规则——详见[设置缓存过滤器规则和一致性影响](#设置缓存过滤器规则和一致性影响)。

## 启用索引服务

{% hint style="warning" %}
**一致性权衡：** 索引服务会主动缓存目录列表。默认缓存规则为 **`immutable`（不可变）**——目录一经列出，Alluxio 会无限期缓存，不再重新检查 UFS。任何在 **Alluxio 之外**对 UFS 进行的写入或删除操作（例如由其他进程或工具执行），都**不会**反映在后续的目录列表中，直到使用 `alluxio index invalidate` 手动使缓存失效。

如果某些目录存在频繁的外部写入或删除，请为这些目录**显式配置** `maxAge` 或 `skipCache` 缓存过滤规则，不要对可变数据依赖 `immutable` 默认值。否则 Alluxio 将持续返回这些目录的过期列表，直到手动使缓存失效。
{% endhint %}

要启用索引服务，请将以下配置添加到所有 Alluxio 节点，包括客户端：

```properties
# disallow clients to list from UFS directly
alluxio.client.list.status.from.ufs.enabled=false
```

此外，还有一些与性能相关的配置可用：

```properties
# set the number of threads that clients use to handle index requests, defaults to the number of available CPU cores
alluxio.client.index.service.parallelism=32
# set the batch size of the index requests that clients fetch from workers or the UFS, defaults to 1000
alluxio.client.index.service.list.batch.size=1000
```

`alluxio.client.index.service.parallelism` 控制客户端用于处理目录列表请求的线程数。它默认为客户端节点上可用的CPU核心数。如果工作负载涉及大量并发列表请求，将其设置为更大的值可能有助于提高性能。

`alluxio.client.index.service.list.batch.size` 控制客户端每次从worker节点上的列表缓存接收的批处理大小。较小的批处理有助于减少客户端和worker上的峰值内存使用，但可能无法充分利用客户端和worker之间的带宽。较大的值可以减少客户端和worker之间的往返次数，从而提高列表性能，但也会在两侧产生更高的内存占用。

重新启动节点以应用配置。

索引服务可通过Alluxio Java API、POSIX API和S3 API使用。

通过Alluxio CLI列出：

```console
# bin/alluxio fs ls /s3_tables
```

在[使用FUSE挂载Alluxio](/ee-ai-cn/data-access/fuse-based-posix-api.md)后通过POSIX API列出：

```console
# ls /mnt/alluxio_fuse/s3_tables
```

通过S3 API使用[ListObjects](/ee-ai-cn/reference/s3-api-usage.md#listobjectsv2)操作列出：

```console
# aws s3 ls --endpoint-url http://worker_hostname:29998/ s3://s3_tables/
```

### 设置缓存过滤器规则和一致性影响

当客户端希望通过索引服务列出目录时，如果目标目录已被缓存，索引服务可能会重用其缓存版本，或者在未缓存时从UFS加载。有时，即使目录的内容已被缓存，也可能因为缓存根据用户偏好过期而无法重用。索引服务通过使用[缓存过滤器](https://documentation.alluxio.io/ee-ai-cn/performance/pages/YDY8IXmveHXAHBwQ8zU3#控制缓存内容缓存过滤策略)配置支持细粒度的目录缓存过滤器规则。然后，索引服务将参考配置的缓存过滤器规则来决定是否可以重用目标目录的缓存版本。

以下示例显示了一个配置，其中不同的缓存过滤器规则应用于不同的目录：

```json
{
  "apiVersion": "1",
  "metadata": {
    "maxAge": {
      "s3://tables/daily_partitions/?$": "4h"
    },
    "skipCache": [
      "s3://tables/intermediate_temp_tables/?$"
    ],
    "defaultType": "immutable"
  },
  "data": {
    "defaultType": "immutable"
  }
}
```

当目录在UFS中的内容发生变化时，即添加了新文件或删除了现有文件，通过索引服务进行的列表将根据该目录上设置的缓存过滤器规则反映这些变化。

可以对目录设置3种不同类型的规则：

1. **最长存活时间**

   在上面的示例中，目录`s3://tables/daily_partitions/`包含每天生成的表的增量更新。此目录设置为最长存活时间为4小时，这意味着目录列表的陈旧缓存版本最多存在4小时。换句话说，在生成新分区后，用户最多需要等待4小时才能在目录列表中看到它。
2. **跳过缓存**

   目录`s3://tables/intermediate_temp_tables`包含作为数据处理管道中间产物创建的临时表，它们需要在创建后立即在列表中可见。此目录设置为跳过缓存，这意味着列出此目录将始终调用UFS并返回最新内容。
3. **不可变**

   默认的缓存过滤器规则设置为不可变，因此任何其他未在缓存过滤器配置中明确列出的目录都被视为不可变。不可变目录将在首次通过Alluxio列出时加载一次，索引服务将不再检查UFS以查看其内容是否已更改。这种不可变类型适用于大多数表示永不更改的静态数据集的目录。

[缓存过滤器](https://documentation.alluxio.io/ee-ai-cn/performance/pages/YDY8IXmveHXAHBwQ8zU3#控制缓存内容缓存过滤策略)的文档详细介绍了不同类型的缓存过滤器规则，并为不同用例提供了所需组合的建议。

请注意，在上面的示例中，目录路径以`$`结尾，表示指定的缓存控制策略仅应用于目录本身，而不递归地应用于其中的文件和子目录。正则表达式还通过`/?`容忍可选的尾部斜杠。您可以使用`bin/alluxio fs ls -c /path`检查不同目录和文件上的有效缓存过滤器规则：

```console
# ./bin/alluxio fs ls -c /s3_tables
              0                 08-01-2024 20:00:01:000  DIR [  MaxAge(14400s)/Immutable     ] /s3_tables/daily_partitions
              0                 08-01-2024 20:00:01:000  DIR [       SkipCache/Immutable     ] /s3_tables/intermediate_temp_tables
              0                 08-01-2024 20:00:01:000  DIR [       Immutable/Immutable     ] /s3_tables/permanent_tables
              0                 08-01-2024 20:00:01:000 FILE [       Immutable/Immutable     ] /s3_tables/README.md
```

请注意，可以对目录及其包含的文件设置不同的缓存过滤器规则。在上面的示例中，尽管`/s3_tables/intermediate_temp_tables`设置为跳过缓存，但根据默认类型，其中的文件和子目录是不可变的：

```console
# ./bin/alluxio fs ls -c /s3_tables/intermediate_temp_tables
              0                 08-01-2024 20:00:02:000  DIR [       Immutable/Immutable     ] /s3_tables/intermediate_temp_tables/__temp__
              0                 08-01-2024 20:00:05:000 FILE [       Immutable/Immutable     ] /s3_tables/intermediate_temp_tables/part1.orc
              0                 08-01-2024 20:00:09:000 FILE [       Immutable/Immutable     ] /s3_tables/intermediate_temp_tables/part2.orc
```

需要注意的是，如果一个目录被设置为具有不可变或最长存活时间的可缓存性，即使直接通过Alluxio对其进行更改，这些更改也不会立即反映出来。如果它被设置为不可变，请使用`bin/alluxio index invalidate`命令使现在过时的缓存失效。如果它被设置为具有最长存活时间，那么陈旧的缓存列表将在指定的存活时间过后自动刷新。您也可以使用invalidate命令手动使缓存失效，并在此后强制立即刷新。

### 手动刷新陈旧列表

在极少数情况下，对被视为不可变的目录进行了不可预见的更新，为了让Alluxio知道这一变化，管理员可以手动使缓存的目录列表失效。在下一次访问时，索引服务将从UFS重新加载目录，从而获取更改。

管理员可以使用`index invalidate`命令使缓存的目录失效。例如：

```console
bin/alluxio index invalidate --path /s3_tables/permanent_tables
```

这将使`/s3_tables/permanent_tables`的列表缓存失效，并在下一次访问时强制从UFS更新。
