# 持久化缓存

开箱即用，Prefect Core不会永久保存数据。所有数据，结果和缓存状态都存储在运行该flow的Python进程的内存中。但是，Prefect Core提供了所有必要的钩子，用于在外部位置持久/查询数据。如果你需要开箱即用的持久层，则可以考虑使用Prefect Cloud。

Prefect提供了几种处理缓存数据的方法。在任何可能的情况下，缓存都将自动进行，或以最少的用户输入触发。

* 缓存输入（Input Caching）
* 缓存输出（Output Caching）
* 检查点（Checkpointing）

## 缓存输入

在运行Prefect flow时，通常有一些需要在将来重新运行的task。例如，当task失败并需要重试时，或者task具有**manual\_only**触发器时，可能会发生这种情况。

每当Prefect检测到将来需要运行某个task时，它将自动缓存该task需要运行的所有信息，并将其存储在结果状态中。下次Prefect遇到该task时，关键信息将反序列化并用于运行task。

> **自动缓存**
>
> 缓存输入是自动缓存。Prefect会在必要时自动应用它。

## 缓存输出

有时，最好缓存task的输出，以避免将来重新计算它。这种模式的常见示例包括不太可能更改的昂贵或费时的计算。在这种情况下，用户可以指定应该将task缓存一定的持续时间，或者只要满足某些条件即可。

这种机制有时称为“时间旅行”，因为它使一个flow运行中计算出的结果可用于其他运行。

缓存输出由三个task参数控制：**cache\_for**，**cache\_validator**和**cache\_key**。

* cache\_for：一个时间长度，表示应将输出缓存多长时间
* cache\_validator：一个可调用对象，表示缓存应如何过期。默认值为**duration\_only**，这意味着缓存将在**cache\_for**的持续时间内处于有效状态。其他验证器可以在**prefect.engine.cache\_validators**中找到，并且包括用于在task接收到不同的输入或flow以不同的参数运行时失效缓存的机制
* cache\_key：用于存储输出缓存的可选参数；指定此参数将允许不同的task以及不同的flow共享一个公共缓存

```python
# this task will be cached for 1 hour
task_1 = prefect.Task(
    cache_for=datetime.timedelta(hours=1))

# this task will be cached for 1 hour, but only if the flow is run with the same parameters
task_2 = prefect.Task(
    cache_for=datetime.timedelta(hours=1),
    cache_validator=prefect.engine.cache_validators.all_parameters)
```

> **缓存存储在上下文中**
>
> 注意，在本地运行Prefect Core时，task的缓存状态将存储在内存的prefect.context的对象中。

## 检查点

通常，将task的数据保存在外部存储很有用。你总是可以将此逻辑直接直接写入task本身，但这有时会使测试变得困难。Prefect提供了task“检查点”的概念，以确保每次成功运行task时都会调用其结果处理器。要配置用于检查点的task，就得提供结果处理器，并在task初始化时设置**checkpoint=True**：

```python
from prefect.engine.result_handlers import LocalResultHandler
from prefect import task, Task


class MyTask(Task):
    def run(self):
        return 42


# create a task via initializing our custom Task class
class_task = MyTask(
    checkpoint=True, result_handler=LocalResultHandler(dir="~/.prefect")
)


# create a task via the task decorator
@task(checkpoint=True, result_handler=LocalResultHandler(dir="~/.prefect"))
def func_task():
    return 99
```

Prefect Core中的默认设置是关闭检查点，Prefect Cloud 0.9.1+中的默认设置是打开检查点。有关更多信息，阅读有关[结果和结果处理器](https://docs.prefect.io/core/concepts/results.html)的概念文档以及有关[使用结果处理器](https://docs.prefect.io/core/advanced_tutorials/using-result-handlers.html)的设置教程。

* [Prefect官网](https://www.prefect.io/)
* [英版原文](https://docs.prefect.io/core/concepts/persistence.html)
* [联系译者](https://github.com/listen-lavender)


---

# 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://listen-lavender.gitbook.io/prefect-docs/coreconcepts/persistcache.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.
