為大負荷設計的 Filecoin 索引器可擴展方案
這篇文章描述了一個簡單的策略,可將大量湧入的索引負荷分散到由索引器節點組成的索引池中。同時,它讓這個索引池具備可擴展性。
索引器擴容的最終目標是10\^{15} 個索引。這並非存儲數據的字節大小,而是存儲索引的數量。一個索引實際上就是一張描述了CID標識與內容提供者數據之間關係的映射圖。實際的數據規模將會遠大於此。目前,我們可處理約10\^{12}個索引,隨著時間的推移,我們會通過一列步驟向最終的擴容目標前進。
目前,大部分的索引負荷是由湧入的索引數據構成的。新增的數據可能超過單一的索引器能夠承受的範圍(速率和數量),它還在极速增加。因此,目前擴容路上最迫切的目標,就是處理增加中的湧入負荷。
方案:處理索引湧入的簡單策略
數據湧入
一個索引器接收到某個發布者傳來的"announce"消息,宣布已經有新的索引數據廣告時,就會發生數據湧入。作為回應,該索引器會從發布者那裡檢索所有尚未檢索過的索引數據。隨著發布者數量增加,在某個時候,單一的索引器節點將無法跟上新增索引數據發布的速率,也可能沒有足夠的存儲空間來全部存儲這些數據。
分散湧入負荷
索引器擴容處理擁堵負載,是基於一個簡單策略------將湧入的索引負荷分散到由索引器節點組成的索引池中,這樣就能根據容量需求來增加節點,而不需要將數據到處移動來重新達到均衡。它先是分配不同的內容 發布者 給不同的索引節點,這樣每個節點可以處理湧入負荷的一部分。這是通過使用單獨的輕量服務Assigner Service來實現的,後者不屬於關鍵的索引湧入路徑的一部分。
當一個索引器達到了配置的存儲限制後,它就會停止吸納新增的索引數據,而索引池裡的其他索引器會從分配給完整索引器的發布者那裡恢復吸納數據。如果存儲容量和湧入負荷分配需求增加, 池子裡就會增加更多的索引器節點。
這個擴容策略的三個主要組件是:
分配服務(Assigner Service):它將發布者分配給索引器。
索引器凍結模式(Indexer Frozen Mode):這種索引器運作模式裡,新內容不會被索引。
移交發布者任務:將凍結中的索引器的發布者任務重新分配給活躍的索引器,以在凍結索引器停止運行後恢復索引。
這篇文章會概括描述這些組件。可以在設計文檔和設計展示中獲取更多信息。
擴容策略的優缺點
優點:
更少的同步工作:不需要讓每一個索引者與每一個發布者同步。
元數據不會重複發送給多個索引器(這跟密鑰分片key-sharding一樣):元數據只會在處理提供者的索引器上存在。
索引器之間不會分享數據。它們各自管理自己的發布者鏈。
不需要只為了檢查提供者而去閱讀廣告(advertisements),這與提供者分片(provider sharding)一樣。
索引器可有不同的存儲容量。
不需要共識機制。
湧入負荷可重新分配,而無需在索引器之間移動數據。
缺點:
不平均的分配:一些發布者可能會比其他發布者索引更多的數據。
查詢請求需要分散和合併:查詢請求會重複發送給所有索引器,而響應會合併成一個發送給客戶。
提供者更改發布者可導致重複索引(這與提供者分片不一樣)。
增加索引者不會馬上起效,除非一個現有的索引器達到了存儲容量限制。
這方案的整體好處是它的實施方案相對簡單,也能去除擁堵擴容的限制。
分配服務(Assigner Service)
分配服務(AS)負責將發布者分配給在其配置索引器池中的索引者。對一個索引器池來說,它作為單一實例運行在其管理的索引器所在的同一網絡上。一個索引器只能作為一個分配服務的索引器池裡的成員。
除了將新的發布者分配給索引器外,分配服務還檢測檢索器節點是否進入了凍結模式,並負責將發布者從凍結索引器重新分配給非凍結的索引器。索引服務還通過gossip pubsub渠道重新發布直接的HTTP公告,這樣池中的所有索引器都能接收到這些信息。
基於幾個假設,分配服務是用於單個私有部署中使用:任務可以發給任何索引器,所有索引器的管理API是在私有網絡上運行(或類似的受保護網絡),而且也沒有建立任何方式或協議讓不同的參與方管理池子中要添加或移除的節點。
將一個發布者分配給一個索引器
一個索引器接收到某個發布者傳來的"announce"消息,宣布已經有新的索引數據廣告時
分配服務會監聽gossip-sub和直接的HTTP消息------這些消息主要是宣布新廣告(advertisements)可被獲取了。它從每一條消息中讀取發布者信息,並判斷發布者是否已經分配給需要的索引器。如果答案是否定的,該分配服務就會選擇任務量最少的索引器,並將該發布者分配給這個索引器。在分配任務後,索引器會收到來自發布者的公告,並自行處理湧入數據。
索引服務會處理離線的索引器,它所用的方式能避免在索引器池裡過度分配任務。索引服務還支持將特定發布者分配給特定索引器的配置選項。
進一步閱讀材料:
非持久化任務狀態(No Persisted Assignment State)(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#no-persisted-assignment-state) 意味著索引器能在任何時候停止或重啟。
索引器池(An Indexer Pool)(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#indexer-pool) 在某個單一部署中的索引器節點的集合。
任務複製(Assignment Replication)(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#replication) 將發布者分配給多個索引器。
索引器凍結模式
索引器存儲使用觸及到配置 `FreezeAtPercent(\<``https://pkg.go.dev/github.com/ipni/storetheindex/config#Indexer`(https://pkg.go.dev/github.com/ipni/storetheindex/config#Indexer "https://pkg.go.dev/github.com/ipni/storetheindex/config#Indexer")`>)` 的限制後,索引器自動進入"凍結"模式。這個運作模式裡,索引器不再存儲新增的索引數據,但還是會處理索引數據的更新或刪除。一個凍結的索引器不會接受新的發布者任務。在其內部,該索引器追蹤它已讀的每一個廣告鏈,目的是納入(ingesting)廣告(與更新和移除任務相關的)。索引器會持續響應對索引數據的查詢。
索引器也可以通過其管理(admin) API來手動進行凍結。這可以是為了暫時凍結納入數據,直到索引器的存儲容量提升為止(或使用分配服務)。這樣,持續的索引工作可以被其他索引器節點代替。
進一步閱讀材料:
磁碟使用監控(Disk Usage Monitoring)(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#disk-usage-monitoring) 由每一個索引器負責。
凍結的能力不依賴於分配服務(Freeze capability does not depend on AS)(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#freeze-independent-of-assigner)。
解除凍結的能力(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#unfreeze)可讓索引器恢復索引工作。
發布者移交
分配服務定期統計索引器,要是它發現某個索引器被凍結,它就會將該被凍結的索引器分配的發布者重新移交給其他索引器------活躍的索引器會繼續之前凍結索引器上所做的工作。在移交過程中,活躍的索引器也會從凍結的索引器那取得提供者及其相關的進一步信息。
分配服務決定哪一個索引器將接收發布者的移交工作------這與分配新發布者的邏輯一樣。每一個發布者的移交過程都會單獨進行這一步驟,這樣凍結索引器的任務就會分配給池子裡的可用索引器。
進一步閱讀材料:
分配服務可以恢復不完整的移交任務(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#resuming-incomplete-handoff)。
發布者數據在凍結和活躍索引器之間分發。(https://github.com/ipni/storetheindex/blob/main/doc/scaling-design-for-indest.md#publisher-data-spread-across-frozen-and-active-indexers)
設立帶有分配服務的索引器池
這裡(https://github.com/ipni/storetheindex/blob/main/doc/assigner-deployment.md#setting-up-indexer-pool-with-assigner-service) 描述了設立帶有分配服務的索引器池的過程。可概括為以下步驟:
部署索引器(Deploy Indexers)(https://github.com/ipni/storetheindex/blob/main/doc/assigner-deployment.md#deploy-indexers)
部署分配服務(Deploy Assigner Service)(https://github.com/ipni/storetheindex/blob/main/doc/assigner-deployment.md#deploy-assigner-service)
按需部署額外的索引器(Deploy additional Indexers as needed)(https://github.com/ipni/storetheindex/blob/main/doc/assigner-deployment.md#example-assigner-service-configuration)
這裡還提供了分配服務配置模板文件(https://github.com/ipni/storetheindex/blob/main/doc/assigner-deployment.md#example-assigner-service-configuration) 。