任务与异步操作
Meilisearch 使用任务队列来处理异步操作。本深度指南解释了任务的概念、用途以及如何使用 Meilisearch 的 API 来管理它们。
Meilisearch 中的许多操作都是异步处理的。这些 API 请求不会立即处理——相反,Meilisearch 会将它们放入队列并按接收顺序依次处理。
哪些操作是异步的?
所有可能耗时较长的操作都会以异步方式处理。异步处理操作使得 Meilisearch 能够在不影响搜索性能的前提下执行资源密集型任务。
目前,Meilisearch 的异步操作包括:
- 创建索引
- 更新索引
- 交换索引
- 删除索引
- 更新索引设置
- 向索引添加文档
- 更新索引中的文档
- 从索引删除文档
- 取消任务
- 删除任务
- 创建数据转储
- 创建快照
理解任务机制
当 API 请求触发异步流程时,Meilisearch 会创建一个任务并将其放入任务队列中。
任务对象
任务对象包含允许您跟踪进度并在出现问题时进行故障排除的信息。
一个任务对象包含原始请求中没有的数据,例如请求入队时间、请求类型以及任务失败时的错误代码:
如需了解每个任务对象字段的完整说明,请查阅任务 API 参考文档。
任务摘要对象
当你发起异步操作的 API 请求时,Meilisearch 会返回完整 task 对象的摘要版本。
使用摘要任务的 taskUid 可以跟踪任务进度。
任务状态(status)
任务对象始终包含一个表示当前 status 的字段。该字段可能为以下值之一:
enqueued:任务已接收,即将处理processing:任务正在处理中succeeded:任务已成功处理failed:处理任务时发生错误。数据库未做任何更改canceled:任务已被取消
succeeded、failed 和 canceled 状态表示任务已完成。Meilisearch 会将这些任务保留在任务数据库中,但已完成处理。你可以配置 webhook 在任务完成时通知外部服务。
enqueued 和 processing 状态表示任务未完成。Meilisearch 正在处理这些任务或将在未来进行处理。
全局任务
某些任务类型不与特定索引关联,而是应用于整个实例。这类任务被称为全局任务。全局任务的 indexUid 字段始终显示为 null。
Meilisearch 将以下任务类型视为全局任务:
dumpCreation(转储创建)taskCancelation(任务取消)taskDeletion(任务删除)indexSwap(索引交换)snapshotCreation(快照创建)
在受保护的实例中,您的 API 密钥必须拥有对所有索引的访问权限("indexes": [*])才能查看全局任务。
任务队列
创建任务后,Meilisearch 会将其放入队列中。排队的任务按照请求顺序逐个处理。
当任务队列达到其限制(约 10GiB)时,会抛出 no_space_left_on_device 错误。用户需要通过删除任务端点删除任务才能继续写入操作。
任务队列优先级
Meilisearch 将某些任务视为高优先级任务,始终将其置于队列前端。
以下类型的任务会立即被处理:
taskCancelation(任务取消)taskDeletion(任务删除)snapshotCreation(快照创建)dumpCreation(转储创建)
所有其他任务按照入队顺序处理。
任务工作流
当您发起异步操作请求时,Meilisearch 会按照以下统一流程处理所有任务:
- Meilisearch 创建任务,将其放入任务队列,并返回一个简化的
task对象。此时任务status设为enqueued(已入队) - 当任务到达队列前端时,Meilisearch 开始处理它。此时任务
status设为processing(处理中) - Meilisearch 完成任务处理。如果任务成功处理,状态设为
succeeded(成功);如果出现错误,则设为failed(失败)
在异步操作过程中终止 Meilisearch 实例是完全安全的,这永远不会对数据库造成负面影响。
任务批次
Meilisearch 以批次为单位处理任务,通过任务分组实现最佳性能。在大多数情况下,批处理应该是透明的,不会对整个任务工作流产生影响。使用/batches路由可以获取有关批次及其处理方式的更多信息。
取消任务
您可以通过取消任务端点来取消处于enqueued(已入队)或processing(处理中)状态的任务。取消操作会将任务status更改为canceled(已取消)。
终止 Meilisearch 实例不会导致任务被取消。Meilisearch 会丢弃所有processing(处理中)任务的进度,并将其重置为enqueued(已入队)状态。实例重新启动后,任务处理会正常继续。
删除任务
已完成的任务会继续保留在任务列表中可见。如需手动删除,请使用删除任务接口。
Meilisearch 在任务数据库中最多存储 100 万条任务。如果新增任务会导致超出此限制,Meilisearch 会自动尝试删除最旧的 10 万条已完成任务。如果数据库中没有已完成任务,Meilisearch 不会删除任何内容,而是照常将新任务加入队列。
示例
假设您使用添加文档端点向实例添加新文档,并收到一个 taskUid 作为响应。
当您使用该值查询获取任务端点时,会看到任务状态为 enqueued(已排队):
稍后,您再次检查任务进度。此时任务已成功处理,状态变为 succeeded(已完成):
如果任务失败,响应中将包含详细的 error 对象:
如果任务在 enqueued(已排队)或 processing(处理中)状态时被取消,其状态将变为 canceled(已取消),且 canceledBy 字段会有非 null 值。
当任务被删除后,尝试访问该任务将返回 task_not_found 错误。