前往主页Meilisearch 的标志
返回文章
2022年12月12日

零停机索引部署

假设您的数据库发生了需要与生产环境中的 Meilisearch 索引同步的更改。您会怎么做?

Carolina Ferreira
Carolina FerreiraMeilisearch 开发者布道师@CarolainFG
Zero downtime index deployment

Meilisearch v0.30 已于本月早些时候发布。通过此次发布,我们的主要目标是使 Meilisearch 的工作流程尽可能顺畅。毕竟,我们正朝着 v1 版迈进,目的地近在咫尺。为此,实现零停机索引部署是至关重要的一步。我们很高兴地宣布,v0.30 解决了这个问题,使得在生产环境中更新索引比以往任何时候都更加容易。继续阅读以了解更多关于该功能的工作原理!

挑战

假设您的数据库发生了需要与生产环境中的 Meilisearch 索引同步的更改。您会怎么做?如果在 Meilisearch v0.29 中,您可能会

更新索引

🙅‍♀️  很简单,对吧?但如果您曾尝试过,那么您应该已经知道……

It's a trap!

在生产索引接收搜索查询时更新它,可能会导致结果不一致甚至信息丢失。您肯定不想提供这样的搜索体验,对吗?否则,您就不会使用 Meilisearch 了😁

删除索引,创建同名新索引,并重新索引数据

⌛ 每一步都会花费一些时间。即使只是几秒钟,那也是几秒钟的停机时间……而且这至少需要三个请求!这里几秒,那里几秒,加起来就可能导致数分钟的停机时间!不,谢谢。

创建一个新索引并使用不同的名称,将更改在那里进行暂存,然后修改所有客户端以指向新索引

🤔 嗯,这不是最糟糕的选择。但同样,更新客户端会导致停机时间😞 在某些情况下,客户端更新何时推送到生产环境甚至不由开发人员决定。以 iOS 应用为例:Apple 必须在您发布新版本之前进行审核,这可能会严重拖延您的发布计划。

创建一个中间重定向层以避免停机时间

🧞 非常聪明!虽然这是一个好方法,但它并不是最直接的。它需要架构知识、时间和额外的工具。

您是不是很高兴再也不必做这些事情了?

灵丹妙药

Meilisearch 始终致力于提供最佳的开发者体验。

我们的团队在过去几个月里一直努力工作,经过多次迭代,他们提出了一个可以无缝集成到开发者技术栈中的解决方案:索引交换

让我向您展示它是如何工作的。

假设您有一个生产环境中的索引——indexA——您的客户端在此索引中进行搜索。您希望将主数据库中的更改与 Meilisearch 同步。为此,您可以按照以下步骤操作。

步骤 1:创建一个包含最新数据的新索引

首先,您需要创建一个索引——我们称之为 indexA_new——它代表您希望部署到搜索客户端的 indexA 的新版本。添加数据库中的最新文档,并在必要时更新索引设置。

请不要忘记检查所有与索引创建相关的任务是否已成功完成,包括 indexCreationsettingsUpdatedocumentAdditionOrUpdate 任务类型。您可以使用 /tasks 路由来获取它们的进度信息。

步骤 2:测试新索引

在将索引推送到生产环境之前,您需要确保一切都按预期工作。

Meme: image of a city on fire in the middle of a thunderstorm, the text reading: "text in production" they said, "what could go wrong" they said

务必更新您可能随更新数据引入的任何新字段的设置。例如,您可能希望将新字段添加到 searchableAttributesfilterableAttributes 和/或 sortableAttributes。无论何时添加新数据,都不要忘记仔细检查搜索结果的相关性!

👉 请记住,searchableAttributes 列表不仅指定了可搜索的字段,还决定了属性排名顺序。请确保您可能引入的任何新字段都以正确的顺序添加到列表中。

步骤 3:交换索引

一旦您的 indexA_new 成功创建、填充数据并经过测试,就可以通过索引交换进行部署了。为此,请向 /swap-indexes 端点发送一个 POST 请求。在请求体中指定您要交换的索引。由于是交换,顺序无关紧要。

curl 
-X POST 'http://localhost:7700/swap-indexes' 
-H 'Content-Type: application/json' 
--data-binary '[
	{ "indexes": ["indexA", "indexA_new"] }
]'

👉 在受保护的 Meilisearch 实例中,用于交换索引的 API 密钥必须具有 indexes.swap 操作以及您希望交换的索引的访问权限。否则,Meilisearch 将抛出 invalid_api_key 错误。有关创建具有特定权限的 API 密钥的更多信息,请参阅文档

您可以使用响应中的 taskUid,通过 GET /tasks/{task_uid} 端点来跟踪请求的状态。成功的索引交换应如下所示

{
  "uid": 23,
  "indexUid": null,
  "status":"succeeded",
  "type":"indexSwap",
  "details":{
	"swaps": [
  	     {"indexes": ["indexA", "indexA_new"]},
	]
  },
  "duration": "PT1S",
  "enqueuedAt": "2021-08-10T14:29:17.000000Z",
  "startedAt": "2021-08-10T14:29:18.000000Z",
  "finishedAt": "2021-08-10T14:29:19.000000Z"
}

您的索引已在零停机时间内完成交换!indexA 的文档、设置和任务历史(除任何已入队任务外)已与 indexA_new 的相应内容进行了交换。任务历史中所有提及 indexA 的地方都已被 indexA_new 替换,反之亦然(enqueued 任务保持不变)。

Animation illustrating index swapping: an index receives search queries while the another is being created in the background. When the second index is ready, they swap, then the unnecessary index is deleted.

交换后,indexA_new 包含过时内容。您可以删除它,或者将其保留作为备份,以防万一出现问题需要回滚。有备无患!

就是这样!只有三个步骤,如果您喜欢冒险,也可以是两个。这还能更棒吗?

锦上添花之处🍰

如果我告诉您,您只需一个请求就可以交换多个索引,您会怎么想?

我没有开玩笑。单个请求可以交换任意数量的索引对。Meilisearch 可以同时部署所有更改。客户端将立即访问所有索引的新版本,而不会有任何停机时间。

curl 
  -X POST 'http://localhost:7700/swap-indexes' 
  -H 'Content-Type: application/json' 
  --data-binary '[
    {
        "indexes": ["indexA", "indexA_new"]
    },
    {
        "indexes": ["indexB", "indexB_new"]
    },
    {
        "indexes": ["indexC", "indexC_new"]
    }
]'

在上面的示例中,三个交换操作将同时且原子地发生。

等等,什么?

是的,您可以再读一遍。它是原子性的!要么所有索引都成功交换,要么一个也没有。要么所有内容都交换了,要么一个也没有。

这为什么重要?它能防止数据库中的部分更改,确保一致性,从而提供一流的搜索体验。

结论

如前所述,这项功能已经开发了几个月,其灵感都源于用户反馈。我们路线图上的 “交换索引”卡片获得了 38 票以及几乎同样多的评论,解释了这项功能是必不可少的使用场景。以下是我们最喜欢的一些例子

  • “在尝试更改生产数据库规则以获得最佳结果时,这会非常有用。”
  • “如果索引意外地以错误名称创建,或者由于各种原因需要重命名/更改它,这将很有帮助。”
  • “我们需要它来清除所有已删除的项目。”

这些只是几个例子。这类见解对我们的团队非常有帮助,因为它使我们能够根据用户的需求来塑造产品。

尽管非常方便——您可以全面了解所有已提交、正在开发和已发布的功能创意——但路线图只是提供反馈的其中一种方式。

在我看来,GitHub 上的产品讨论区是阐述您需求的最佳场所之一。您可以与 Meilisearch 产品团队直接联系,而且由于它是公开的,任何人都可以参与并丰富这个过程。

最后一个选择是我们全新的 Discord 服务器。请不要犹豫加入我们,谈论您用 Meilisearch 构建了什么、您的用例以及您的具体需求。

无论您选择哪种方式,我们都期待您的反馈!

Meilisearch indexes embeddings 7x faster with binary quantization

Meilisearch 使用二进制量化将嵌入索引速度提高了 7 倍

通过在向量存储 Arroy 中实现二进制量化,已显著减少了大型嵌入的磁盘空间使用量和索引时间,同时保持了搜索相关性和效率。

Tamo
Tamo2024年11月29日
How to add AI-powered search to a React app

如何将 AI 驱动的搜索添加到 React 应用

使用 Meilisearch 的 AI 驱动搜索构建一个 React 电影搜索和推荐应用。

Carolina Ferreira
Carolina Ferreira2024年9月24日
Meilisearch is too slow

Meilisearch 速度太慢

在这篇博文中,我们探讨了 Meilisearch 文档索引器所需的增强功能。我们将讨论当前的索引引擎、其缺点以及优化性能的新技术。

Clément Renault
Clément Renault2024年8月20日