零停機時間索引部署
假設您的資料庫中有變更,需要與生產環境中的 Meilisearch 索引同步。您會怎麼做?

Meilisearch 的 v0.30 版本已於本月稍早發布。我們的首要目標是使 Meilisearch 工作流程盡可能順暢。畢竟,我們正邁向 v1,而我們的目標比以往任何時候都更近了。為此,具有零停機時間的索引部署是至關重要的一步。我們很高興地說,v0.30 解決了這個問題,使在生產環境中更新索引比以往任何時候都更容易。請繼續閱讀以了解有關該功能如何運作的更多資訊!
挑戰
假設您的資料庫中有變更,需要與生產環境中的 Meilisearch 索引同步。您會怎麼做?好吧,如果您使用的是 Meilisearch v0.29,您可能會
更新您的索引
🙅♀️ 很簡單,對吧?但是如果您曾經嘗試過,那麼您應該已經知道...
在接收搜尋查詢時更新您的生產索引可能會導致結果不一致,甚至遺失資訊。您不希望提供那種搜尋體驗,對吧?否則,您就不會使用 Meilisearch 😁
刪除索引、建立一個具有相同名稱的新索引,然後重新索引資料
⌛ 每個步驟都需要一些時間。即使只是幾秒鐘,也意味著幾秒鐘的停機時間...而且這至少需要三個請求!這裡幾秒鐘加上那裡幾秒鐘可能導致幾分鐘的停機時間!不,非常感謝。
建立一個具有其他名稱的新索引、在那裡暫存變更,然後修改所有客戶端以指向新索引
🤔 嗯,這不是最糟糕的選擇。但是,再次強調,更新客戶端會導致停機時間 😞 在某些情況下,甚至不是由開發人員來決定何時將客戶端更新推送到生產環境。以 iOS 應用程式為例:Apple 必須先審查新版本,才能發布,這可能會嚴重拖累您的發布計畫。
建立一個中間重新導向層以避免停機時間
🧞 非常聰明!雖然這是一個很好的方法,但並不是最直接的方法。它需要架構知識、時間和額外工具。
您是否很高興您再也不需要做這些事情了?
萬靈丹
Meilisearch 一直致力於提供最佳的開發人員體驗。
我們的團隊在過去幾個月中一直努力工作,經過多次迭代,他們提出了一個可以無縫整合到開發人員堆疊中的解決方案:索引交換。
讓我向您展示它是如何運作的。
假設您在生產環境中擁有一個索引—indexA
—您的客戶端在其中進行搜尋。您想要將主要資料庫中的變更與 Meilisearch 同步。為此,您將遵循以下步驟。
步驟 1:使用最新資料建立新索引
首先,您需要建立一個索引—讓我們稱之為 indexA_new
—代表您想要部署到搜尋客戶端的 indexA
的新版本。從您的資料庫新增最新的文件,並在必要時更新索引設定。
別忘了檢查與索引建立相關的所有任務是否已成功完成,包括 indexCreation
、settingsUpdate
和 documentAdditionOrUpdate
任務類型。您可以使用 /tasks
路由 來獲取有關其進度的資訊。
步驟 2:測試新索引
在將您的索引傳送到生產環境之前,您要確保一切都按預期運作。
請務必為您可能使用更新的資料引入的任何新欄位更新設定。例如,您可能希望將新欄位新增至 searchableAttributes
、filterableAttributes
和/或 sortableAttributes
。每次新增新資料時,請不要忘記仔細檢查搜尋結果的相關性!
👉 請記住,searchableAttributes
清單不僅指定可搜尋的欄位,還指示屬性排名順序。請確保您可能引入的任何新欄位都以正確的順序新增到清單中。
步驟 3:交換索引
一旦您的 indexA_new
已成功建立、填入資料並經過測試,就可以使用索引交換進行部署。為此,請向 /swap-indexes
端點傳送 POST
請求。在有效負載中指定您要交換的索引。由於它是交換,因此順序並不重要。
curl -X POST 'https://127.0.0.1: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
任務保持不變)。
交換後,indexA_new
將包含過時的內容。您可以將其刪除,或將其保留為備份,以防出現問題並且您需要換回。安全總比後悔好!
就這樣!只有三個步驟,如果您喜歡冒險,則只有兩個步驟。這會變得更好嗎?
蛋糕上的櫻桃—是的,複數—🍰
如果我告訴您可以僅用一個請求交換多個索引,那會怎麼樣?
我沒有開玩笑。單個請求可以交換任意多個索引對。Meilisearch 可以同時部署所有變更。客戶端將同時存取所有索引的新版本,而不會有任何停機時間。
curl -X POST 'https://127.0.0.1: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 建立的內容、您的用例和您的特定需求。
無論您選擇哪個選項,我們都期待收到您的來信!