Meilisearch 中的许多操作都是异步处理的。这些 API 请求不会立即处理——相反,Meilisearch 将它们放入队列中,并按照接收顺序处理它们。

哪些操作是异步的?

每个可能需要很长时间才能处理的操作都是异步处理的。异步处理操作允许 Meilisearch 处理资源密集型任务,而不会影响搜索性能。

目前,这些是 Meilisearch 的异步操作:

  • 创建索引
  • 更新索引
  • 交换索引
  • 删除索引
  • 更新索引设置
  • 向索引添加文档
  • 更新索引中的文档
  • 从索引删除文档
  • 取消任务
  • 删除任务
  • 创建转储
  • 创建快照

理解任务

当 API 请求触发异步进程时,Meilisearch 会创建一个任务并将其放入任务队列中。

任务对象

任务是包含信息的对象,这些信息允许您跟踪它们的进度并在出现问题时进行故障排除。

一个任务对象包含原始请求中没有的数据,例如请求何时入队、请求类型以及任务失败时的错误代码。

{
    "uid": 1,
    "indexUid": "movies",
    "status": "enqueued",
    "type": "documentAdditionOrUpdate",
    "canceledBy": null,
    "details": {
        "receivedDocuments": 67493,
        "indexedDocuments": null
    },
    "error": null,
    "duration": null,
    "enqueuedAt": "2021-08-10T14:29:17.000000Z",
    "startedAt": null,
    "finishedAt": null
}

有关每个任务对象字段的详细描述,请查阅任务 API 参考

摘要任务对象

当您对异步操作发出 API 请求时,Meilisearch 会返回完整 task 对象的摘要版本

{
  "taskUid": 0,
  "indexUid": "movies",
  "status": "enqueued",
  "type": "indexCreation",
  "enqueuedAt": "2021-08-11T09:25:53.000000Z"
}

使用摘要任务的 taskUid跟踪任务进度

任务状态

任务总是包含一个指示任务当前状态的字段。该字段可能具有以下值之一:

  • enqueued(已入队):任务已收到,即将处理
  • processing(处理中):任务正在处理
  • succeeded(成功):任务已成功处理
  • failed(失败):处理任务时发生故障。数据库未发生任何更改
  • canceled(已取消):任务已取消

succeeded(成功)、failed(失败)和 canceled(已取消)任务是已完成的任务。Meilisearch 将它们保留在任务数据库中,但已完成处理这些任务。可以配置 Webhook 以在任务完成时通知外部服务。

enqueued(已入队)和 processing(处理中)任务是未完成的任务。Meilisearch 正在处理它们或将来会处理它们。

全局任务

某些任务类型不与特定索引关联,但适用于整个实例。这些任务称为全局任务。全局任务的 indexUid 字段始终显示 null

Meilisearch 将以下任务类型视为全局任务:

在受保护的实例中,您的 API 密钥必须具有访问所有索引的权限 ("indexes": [*]) 才能查看全局任务。

任务队列

创建任务后,Meilisearch 会将其放入队列中。入队任务按请求顺序逐一处理。

当任务队列达到其限制(约 10GiB)时,将抛出 no_space_left_on_device 错误。用户需要使用删除任务端点来删除任务以继续写入操作。

任务队列优先级

Meilisearch 将某些任务视为高优先级,并始终将其放在队列的最前面。

以下类型的任务总是尽快处理:

  1. taskCancelation
  2. taskDeletion
  3. snapshotCreation
  4. dumpCreation

所有其他任务按照入队顺序处理。

任务工作流程

当您请求异步操作时,Meilisearch 按照以下步骤处理所有任务:

  1. Meilisearch 创建一个任务,将其放入任务队列,并返回一个摘要 task 对象。任务状态设置为 enqueued(已入队)
  2. 当您的任务到达队列前端时,Meilisearch 开始处理它。任务状态设置为 processing(处理中)
  3. Meilisearch 完成任务。如果任务成功处理,状态设置为 succeeded(成功),如果出现错误,则设置为 failed(失败)

在异步操作过程中终止 Meilisearch 实例是完全安全的,并且永远不会对数据库造成不利影响。

任务批处理

Meilisearch 以批处理方式处理任务,对任务进行分组以获得最佳性能。在大多数情况下,批处理应该是透明的,对整体任务工作流程没有影响。使用/batches 路由获取有关批处理以及它们如何处理您的任务的更多信息。

取消任务

您可以使用取消任务端点取消处于 enqueued(已入队)或 processing(处理中)状态的任务。这样做会将任务的状态更改为 canceled(已取消)。

终止 Meilisearch 实例时任务不会被取消。Meilisearch 会丢弃所有在 processing(处理中)任务上取得的进展,并将它们重置为 enqueued(已入队)。实例重新启动后,任务处理照常进行。

删除任务

已完成的任务任务列表中仍然可见。要手动删除它们,请使用删除任务路由

Meilisearch 在任务数据库中最多存储 100 万个任务。如果新任务入队会超出此限制,Meilisearch 会自动尝试删除最旧的 10 万个已完成任务。如果数据库中没有已完成任务,Meilisearch 不会删除任何内容,并照常将新任务入队。

示例

假设您使用添加文档端点向您的实例添加新文档,并在响应中收到一个 taskUid

当您使用此值查询获取任务端点时,您会看到它已处于 enqueued(已入队)状态。

{
    "uid": 1,
    "indexUid": "movies",
    "status": "enqueued",
    "type": "documentAdditionOrUpdate",
    "canceledBy": null,
    "details": {
        "receivedDocuments": 67493,
        "indexedDocuments": null
    },
    "error": null,
    "duration": null,
    "enqueuedAt": "2021-08-10T14:29:17.000000Z",
    "startedAt": null,
    "finishedAt": null
}

稍后,您再次检查任务进度。它已成功处理,其状态变为 succeeded(成功)。

{
    "uid": 1,
    "indexUid": "movies",
    "status": "succeeded",
    "type": "documentAdditionOrUpdate",
    "canceledBy": null,
    "details": {
            "receivedDocuments": 67493,
            "indexedDocuments": 67493
    },
    "error": null,
    "duration": "PT1S",
    "enqueuedAt": "2021-08-10T14:29:17.000000Z",
    "startedAt": "2021-08-10T14:29:18.000000Z",
    "finishedAt": "2021-08-10T14:29:19.000000Z"
}

如果任务失败,响应将包含一个详细的 error 对象。

{
    "uid": 1,
    "indexUid": "movies",
    "status": "failed",
    "type": "documentAdditionOrUpdate",
    "canceledBy": null,
    "details": {
            "receivedDocuments": 67493,
            "indexedDocuments": 0
    },
    "error": {
        "message": "Document does not have a `:primaryKey` attribute: `:documentRepresentation`.",
        "code": "internal",
        "type": "missing_document_id",
        "link": "https://docs.meilisearch.com/errors#missing-document-id"
    },
    "duration": "PT1S",
    "enqueuedAt": "2021-08-10T14:29:17.000000Z",
    "startedAt": "2021-08-10T14:29:18.000000Z",
    "finishedAt": "2021-08-10T14:29:19.000000Z"
}

如果任务在 enqueued(已入队)或 processing(处理中)时被取消,则其状态将为 canceled(已取消),并且 canceledBy 字段的值将不为 null

任务被删除后,尝试访问它将返回task_not_found错误。