# 缓存策略

数据进入缓存后，四种机制可让您控制其行为：

| 机制                       | 回答的问题                    | 是否驱逐数据？    |
| ------------------------ | ------------------------ | ---------- |
| **Cache Priority（缓存固定）** | 哪些数据在 LRU 驱逐时应存活最久？      | 否——影响驱逐顺序  |
| **TTL**                  | 无论访问频率如何，数据最多可以在缓存中保留多久？ | 是——基于时间的过期 |
| **Cache Filter**         | 哪些数据应该被缓存？缓存数据需要多新鲜？     | 否——控制准入    |
| **Quota**                | 一个目录树可以占用多少缓存空间？         | 是——强制执行限制  |

{% hint style="info" %}
TTL 与 Cache Priority 相互补充：TTL 控制数据最长可在缓存中保留多久；Priority 控制空间不足时优先驱逐哪些数据。两者可结合使用，实现更全面的缓存管理。
{% endhint %}

### 防止驱逐：缓存固定

**Cache Priority** 是 Alluxio 的缓存固定机制。将路径标记为 `HIGH` 优先级，可确保其始终在低优先级数据*之后*才被驱逐——实际效果是：只要还有低优先级数据可驱逐，高优先级数据集就会一直保留在缓存中。

优先级分三个级别：`HIGH`、`MEDIUM` 和 `LOW`。当需要缓存空间时，Alluxio 优先驱逐 `LOW`，其次是 `MEDIUM`，最后是 `HIGH`。同一优先级层级内，由基础驱逐策略（默认 LRU）决定顺序。

**典型使用场景：**

* 推理期间不能冷启动的微调模型
* 多个并发查询共享的维度表
* 任何缓存未命中代价极高的数据集

加载数据后再 pin 的完整流程，请参阅[缓存加载](/ee-ai-cn/cache/loading-data-into-the-cache.md)。

#### 配置

要启用缓存优先级，必须在所有客户端和 Worker 节点的 `alluxio-site.properties` 中设置以下属性：

```properties
alluxio.worker.page.store.evictor.priority.enabled=true
```

由于优先级规则持久化在 etcd 中，还必须确保 etcd 连接详情配置正确。

#### 基本操作

优先级规则使用 `alluxio priority` CLI 管理。有关命令和标志的完整列表，请参阅 [CLI 指南](/ee-ai-cn/reference/user-cli.md)。

**添加优先级规则：**

```shell
bin/alluxio priority add --path s3://bucket/critical_data --priority high
```

**列出优先级规则：**

```shell
bin/alluxio priority list
```

**更新优先级规则：**

```shell
bin/alluxio priority update --path s3://bucket/data --priority medium
```

**移除优先级规则：**

```shell
bin/alluxio priority remove --path s3://bucket/data
```

对于具有相同优先级级别的文件，由标准驱逐策略（默认 LRU）决定驱逐顺序。有关标志的完整列表，请参阅 [CLI 指南](/ee-ai-cn/reference/user-cli.md)。

### 控制缓存多长时间：生存时间（TTL）

\*\*生存时间（TTL）\*\*功能允许您为特定目录中的缓存数据定义最大生命周期。一旦文件的缓存时长超过其 TTL，Alluxio 将在下次定期检查时自动驱逐该文件。TTL 计时器从数据首次加载到 Alluxio 缓存时开始计时。

适用场景：

* 自动清理临时或时间敏感的数据。
* 确保过时数据不会无限期地残留在缓存中。
* 通过限制敏感数据的生命周期来满足合规性要求。

#### 配置

要使用基于 TTL 的驱逐，必须在 `alluxio-site.properties` 中启用该功能：

```properties
alluxio.ttl.policy.enabled=true
```

配置扫描间隔同样重要，它决定了 Worker 检查过期数据的频率：

```properties
# 默认为 1 小时。为生产环境设置更长的间隔。
alluxio.ttl.eviction.check.interval=1h
```

过短的间隔会产生不必要的系统开销。建议设置一个兼顾清理及时性与性能的值，在许多生产场景中推荐使用 `24h`。若配置的 TTL 短于扫描间隔，过期数据只会在下次扫描时被驱逐，而非立即驱逐。

#### 基本操作

TTL 规则使用 `alluxio ttl` CLI 管理。有关命令和标志的完整列表，请参阅 [CLI 指南](/ee-ai-cn/reference/user-cli.md)。

**添加 TTL 规则**（在 `/s3/daily_reports/` 上设置 24 小时）：

```shell
bin/alluxio ttl add --path /s3/daily_reports/ --time 24h
```

**列出 TTL 规则：**

```shell
bin/alluxio ttl list
```

```console
Listing all TTL policies
/s3/daily_reports/     TTL: 24 hours
```

**更新 TTL 规则：**

```shell
bin/alluxio ttl update --path /s3/test_folder/ --time 30min
```

{% hint style="warning" %}
避免设置非常短的 TTL（如 `5s`）。过期条目按配置的 `alluxio.ttl.eviction.check.interval`（默认 `1h`）扫描，短于扫描间隔的 TTL 没有实际效果。
{% endhint %}

**移除 TTL 规则：**

```shell
bin/alluxio ttl remove --path /s3/test_folder
```

{% hint style="info" %}
TTL 驱逐是**惰性执行**的：数据到期后规则本身不会被自动删除。驱逐完成后，规则仍保持有效，若同路径数据再次被加载，规则将重新生效。不再需要该规则时，请用 `ttl remove` 显式删除。
{% endhint %}

与配额类似，TTL 规则是分层的。若多条 TTL 规则适用于同一文件，路径匹配最具体的规则优先。

### 控制缓存内容：缓存过滤策略

**缓存过滤策略**功能默认启用，允许您根据文件路径创建规则，确定哪些文件应该或不应该被缓存。这对于排除频繁更改的文件、临时文件或缓存后性能提升不大的数据非常有用。

默认情况下，Alluxio 使用\*\*不可变（Immutable）\*\*策略，即在首次读取时缓存数据，之后不再检查 UFS 的更新。您可以通过为特定路径定义规则来覆盖此行为。

Alluxio 为文件定义了三种过滤模式：

* **不可变（Immutable）**：文件的数据和元数据永远不会改变。Alluxio 缓存一次后永不检查 UFS 的更新。这是默认行为，也是性能最高的选项。
* **跳过缓存（Skip Cache）**：文件的数据和元数据不应在 Alluxio 中缓存。对该文件的所有请求都将直接转发到 UFS。适用于缓存一致性难以维护的高度易变文件。
* **最大存活时间（Max Age）**：文件的数据和元数据可能会更改。您可以指定一个持续时间（如 `10m`），过后缓存的副本被视为过时。Alluxio 将在下次访问时重新检查 UFS 以获取更新版本。

#### 过滤模式示例

以下示例展示了不同过滤规则背后的逻辑。使用 ETCD 时，通常通过 Alluxio CLI 或 REST API 应用这些规则。有关详细命令用法，请参阅 [CLI 指南](/ee-ai-cn/reference/user-cli.md)。

**不可变：适用于永不更改的数据**

这是性能最高的选项，应作为大多数数据的默认设置。文件标记为 `immutable` 后，Alluxio 缓存一次，永不检查 UFS 的更新。

**一致性**：此策略仅在 **UFS 中的源文件确实永不更改**时提供强一致性。若源文件在缓存后被修改，Alluxio 将继续提供旧的过时版本，导致永久性不一致。

```json
{
  "apiVersion": "1",
  "metadata": {
    "defaultType": "immutable"
  },
  "data": {
    "defaultType": "immutable"
  }
}
```

**跳过缓存：适用于易变或很少使用的数据**

如果数据频繁更改（如临时脚本）或不值得缓存，可使用 `skipCache` 规则将其排除。对这些文件的所有请求都将直接从 UFS 提供。

**一致性**：此策略提供**强一致性**，因为它绕过缓存并直接从事实来源（UFS）读取。一致性保证与底层存储系统相同。

```json
{
  "apiVersion": "1",
  "metadata": {
    "skipCache": ["file://dev/scripts/.*"],
    "defaultType": "immutable"
  },
  "data": {
    "skipCache": ["file://dev/scripts/.*"],
    "defaultType": "immutable"
  }
}
```

**最大存活时间：适用于有界过时的数据**

对于定期更新的数据，可以设置 `maxAge`，告知 Alluxio 在指定持续时间内将缓存数据视为新鲜。过期后，Alluxio 将在下次访问时检查 UFS 以获取更新版本。

**一致性**：此策略提供**有界过时**。客户端可能读取过时的数据版本，但过时程度不超过指定的 `maxAge` 持续时间。它在性能与新鲜度之间取得平衡，但不保证强一致性。

```json
{
  "apiVersion": "1",
  "metadata": {
    "maxAge": {"s3://datalake/tables/pipeline/sales/.*": "1h"},
    "defaultType": "immutable"
  },
  "data": {
    "defaultType": "immutable"
  }
}
```

此配置适用于可变数据集——您可以容忍一定程度的过时，以换取更高的性能。

若要在将 `defaultType` 设置为 `maxAge` 时指定持续时间，请设置 `defaultMaxAge`：

```json
{
  "apiVersion": "1",
  "metadata": {
    "defaultType": "maxAge",
    "defaultMaxAge": "10min"
  },
  "data": {
    "defaultType": "immutable"
  }
}
```

#### `maxAge` 缓存过滤器与 TTL 规则的区别

`maxAge` 缓存过滤器与 TTL 规则在功能上看起来相似，当用户希望确保缓存数据有界过时时可能难以选择。`maxAge` 缓存过滤器在数据访问时生效，若缓存已达到最大存活时间则与 UFS 重新验证。因此，过期缓存项不会自动重新验证，直到被访问时才触发。TTL 规则的执行独立于数据访问，缓存数据一旦 TTL 到期即被驱逐，即使未被访问也是如此。缓存项被 TTL 清除之前不会重新验证，即使其在 UFS 中完全没有变化。因此，若要确保缓存数据在访问时始终是最新的，请使用 `maxAge` 缓存过滤器；若要确保缓存数据不会超过某段时间仍残留在缓存中，请使用 TTL 规则。某些场景下，可以同时使用这两个功能以实现更全面的缓存管理。

### 控制缓存多少：缓存配额

**缓存配额**允许管理员限制特定目录树中文件可使用的缓存空间总量。这对于多租户环境或确保没有单个数据集或用户独占集群缓存资源至关重要。

当目录的配额超出时，Alluxio 将采取措施强制执行限制。默认情况下，停止为该目录缓存新数据（`NO_CACHE`）并触发驱逐以将使用量降回限制以下。

#### 配置

要使用基于目录的配额，必须在 `alluxio-site.properties` 中启用该功能并指定 Coordinator 地址：

```properties
# 启用基于目录的集群配额功能
alluxio.quota.enabled=true

# 配置 Coordinator 地址
alluxio.coordinator.hostname=<host>
alluxio.coordinator.rpc.port=<port>
```

您也可以通过 `alluxio.quota.limit.exceeded.action` 属性控制超出配额时的行为。可用操作：

* **`NO_CACHE`（默认）**：停止在该路径下缓存新数据，但允许从 UFS 提供读取请求。
* **`REJECT`**：拒绝会在该路径下创建缓存数据的新写入请求，并向客户端返回异常。
* **`NOOP`**：继续允许缓存新数据，依靠驱逐来管理空间。若写入速率高于驱逐速率，此选项可能不足。

#### 基本操作

使用 `alluxio quota` CLI 管理配额。有关命令和标志的完整列表，请参阅 [CLI 指南](/ee-ai-cn/reference/user-cli.md)。

**添加配额**（在 `/s3/data` 上设置 10 GB）：

```shell
bin/alluxio quota add --directory /s3/data/ --quota-size 10GB
```

```console
Successfully added quota definition for path /s3/data/ with size 10GB.
```

**列出配额：**

```shell
bin/alluxio quota list
```

```console
Alluxio path                    	        Capacity	            Used	State
/s3/data                    	             10.00GB	     Calculating	Available
```

**更新配额：**

```shell
bin/alluxio quota update --directory /local/data/ --quota-size 100GB
```

**移除配额：**

```shell
bin/alluxio quota remove --directory /s3/data
```

配额也支持嵌套。例如，可以为一个团队的目录分配 10 GB 配额，再为该团队内的各个项目细分更小的配额。


---

# Agent Instructions: 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:

```
GET https://documentation.alluxio.io/ee-ai-cn/cache/managing-data-in-the-cache.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
