# 元数据列表

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

## 概述

索引服务是一个分布式的目录列表缓存服务，类似于普通文件的元数据和数据缓存。它利用缓存内容来提供比直接访问 UFS 更快的目录列表。在 client 侧，它支持并行处理目录条目，从而提高列表操作的性能。

索引服务还与[Cache Filter](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/cache/cache-filter-policy)集成，支持为不同目录设置细粒度的缓存过滤规则。

## 启用索引服务

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

```properties
# 禁止 client 直接从 UFS 获取文件列表
alluxio.client.list.status.from.ufs.enabled=false
```

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

```properties
# 设置 client 用于处理索引请求的线程数量，默认为可用 CPU 核的数量
alluxio.client.index.service.parallelism=32
# 设置 client 从 worker 或 UFS 中获取的批量(batch)索引请求大小，默认为 1000
alluxio.client.index.service.list.batch.size=1000
```

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

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

重启节点以应用配置。

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

通过 Alluxio CLI 列出：

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

在[使用 Fuse 挂载 Alluxio](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/data-access/fuse-based-posix-api)后通过 POSIX API 列出文件

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

通过 S3 API [ListObjects](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/reference/s3-api-usage#listobjectsv2) 操作列出文件：

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

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

当 client 要通过索引服务列出目录时，索引服务可能会重用目标目录的缓存版本（如果已缓存），否则将会从 UFS 加载。 有时候，即使目录的内容已被缓存，但根据用户的偏好，缓存可能已过期，导致不能重用。 索引服务通过使用[Cache Filter](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/cache/cache-filter-policy) 配置支持细粒度的目录缓存过滤规则。 索引服务将参考已配置的缓存过滤规则，决定是否可以重用目标目录的缓存版本。

以下配置示例展示将不同的缓存过滤规则应用于不同目录：

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

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

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

1. **Max Age**

   在上述示例中，目录 `s3://tables/daily_partitions/` 包含每天生成的表的增量更新。 该目录的最大时限被设置为 4 小时，这意味着目录的缓存列表中可能包含的陈旧版本最多存在 4 小时。也就是说，在生成新分区后，用户要在目录列表中看到该分区须最多等待 4 小时。
2. **Skip Cache**

   目录 `s3://tables/intermediate_temp_tables` 包含作为数据处理工作流中间产物创建的临时表，这些表需要在创建后立即在列表中可见。 该目录设置为跳过缓存，这意味着列出该目录时将始终访问 UFS，并返回最新的内容。
3. **Immutable**

   默认的缓存过滤规则设置为不可变，因此任何未在缓存过滤配置中明确列出的目录都被视为不可变。 不可变目录将在第一次通过 Alluxio 列出时被加载一次，之后索引服务将不会再访问 UFS 以查看其内容是否发生变化。 该不可变模式适用于大多数只包含不会发生更改的静态数据集的目录。

有关[Cache Filter](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/cache/cache-filter-policy#不同使用场景下的推荐缓存过滤规则)的文档提供了更多关于不同类型缓存过滤规则的详细信息，并对不同使用场景下的推荐组合进行了说明。

请注意，在上面的示例中，目录路径以`$` 结尾，表示指定的缓存控制策略仅应用于该目录本身，而非其中的文件和子目录（即不会递归应用）。 正则表达式还允许使用可选的尾部斜杠`/?`。 可以使用`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 获取更新。
