大規模了解實時查詢

閱讀本文檔,以獲取有關將無伺服器應用程式擴展到每秒數千次操作或數十萬並髮用戶之外的指南。本文檔包含進階主題,可協助您深入了解系統。如果您剛開始使用 Cloud Firestore,請參閱快速入門指南

Cloud Firestore 和 Firebase 行動/Web SDK 為開發無伺服器應用程式提供了強大的模型,其中客戶端程式碼直接存取資料庫。 SDK 可讓客戶端即時監聽資料更新。您可以使用即時更新來建立不需要伺服器基礎架構的響應式應用程式。雖然啟動和運行某些功能非常容易,但它有助於了解構成 Cloud Firestore 的系統中的限制,以便您的無伺服器應用程式在流量增加時能夠擴展並表現良好。

有關擴展應用程式的建議,請參閱以下部分。

選擇靠近您的使用者的資料庫位置

下圖展示了即時應用程式的架構:

即時應用程式架構範例

當用戶裝置(行動裝置或 Web)上執行的應用程式建立與 Cloud Firestore 的連線時,該連線將路由到資料庫所在區域中的 Cloud Firestore 前端伺服器。例如,如果您的資料庫位於us-east1中,連線也會轉到同樣位於us-east1中的 Cloud Firestore 前端。這些連接是長期存在的,並保持開啟狀態,直到被應用程式明確關閉。前端從底層 Cloud Firestore 儲存系統讀取資料。

使用者的實體位置與 Cloud Firestore 資料庫位置之間的距離會影響使用者體驗的延遲。例如,如果印度的用戶的應用程式與北美Google Cloud 區域的資料庫進行通信,那麼與資料庫距離較近(例如印度或亞洲其他地區)的情況相比,用戶可能會發現體驗速度較慢且應用程式不夠流暢。 。

可靠度設計

以下主題可以提高或影響您的應用程式的可靠性:

啟用離線模式

Firebase SDK 提供離線資料持久性。如果使用者裝置上的應用程式無法連接到 Cloud Firestore,則該應用程式可以透過使用本機快取的資料來保持可用。即使使用者遇到網路連線不穩定或完全無法存取數小時或數天的情況,也能確保資料存取。有關離線模式的更多詳細信息,請參閱啟用離線資料

了解自動重試

Firebase SDK 負責重試操作並重新建立斷開的連線。這有助於解決由重新啟動伺服器或客戶端與資料庫之間的網路問題引起的暫時性錯誤。

在區域和多區域位置之間進行選擇

在區域位置和多區域位置之間進行選擇時需要進行一些權衡。主要差異在於資料的複製方式。這可以提高應用程式的可用性保證。多區域實例可提供更強的服務可靠性並提高資料的持久性,但代價是成本。

了解即時查詢系統

即時查詢,也稱為快照偵聽器,讓應用程式偵聽資料庫中的更改,並在資料發生更改時立即取得低延遲通知。應用程式可以透過定期輪詢資料庫以獲取更新來獲得相同的結果,但它通常更慢、更昂貴並且需要更多程式碼。有關如何設定和使用即時查詢的範例,請參閱以取得即時更新。以下部分詳細介紹了快照偵聽器的工作原理,並描述了在保持效能的同時擴展即時查詢的一些最佳實踐。

想像一下,兩個用戶透過使用其中一個行動 SDK 建立的訊息應用程式連接到 Cloud Firestore。

用戶端 A 寫入資料庫以新增和更新名為chatroom的集合中的文件:

collection chatroom:
    document message1:
      from: 'Sparky'
      message: 'Welcome to Cloud Firestore!'

    document message2:
      from: 'Santa'
      message: 'Presents are coming'

客戶端 B 使用快照偵聽器偵聽同一集合中的更新。每當有人建立新訊息時,客戶端 B 都會立即收到通知。下圖顯示了快照偵聽器背後的架構:

快照偵聽器連接的架構

當客戶端 B 將快照偵聽器連接到資料庫時,會發生以下事件序列:

  1. 用戶端 B 開啟與 Cloud Firestore 的連接,並透過 Firebase SDK 呼叫onSnapshot(collection("chatroom"))來註冊偵聽器。此監聽器可以保持活躍數小時。
  2. Cloud Firestore 前端查詢底層儲存系統以引導資料集。它會載入匹配文檔的整個結果集。我們將此稱為輪詢查詢。然後,系統會評估資料庫的Firebase 安全性規則,以驗證使用者是否可以存取此資料。如果使用者被授權,資料庫將資料傳回給使用者。
  3. 然後,客戶端 B 的查詢進入監聽模式。偵聽器向訂閱處理程序註冊並等待資料更新。
  4. 客戶端 A 現在發送寫入操作來修改文件。
  5. 資料庫將文檔變更提交到其儲存系統。
  6. 在事務上,系統將相同的更新提交到內部變更日誌。變更日誌對發生的變更建立了嚴格的順序。
  7. 變更日誌又將更新的資料扇出到訂閱處理程序集區。
  8. 執行反向查詢匹配器以查看更新的文件是否與任何目前註冊的快照偵聽器相符。在此範例中,文件與用戶端 B 的快照偵聽器相符。顧名思義,您可以將反向查詢匹配器視為正常的資料庫查詢,但以相反的方式完成。它不是透過搜尋文檔來尋找與查詢相符的文檔,而是透過有效率地搜尋查詢來尋找與傳入文檔相符的文檔。找到符合項目後,系統會將相關文件轉送給快照偵聽器。然後,系統評估資料庫的Firebase 安全性規則,以確保只有授權使用者才能接收資料。
  9. 系統將文件更新轉送至客戶端 B 裝置上的 SDK,並觸發onSnapshot回呼。如果啟用本機持久性,SDK 也會將更新套用到本機快取。

Cloud Firestore 可擴充性的關鍵部分取決於從變更日誌到訂閱處理程序和前端伺服器的扇出。扇出使單一資料變更能夠有效傳播,為數百萬即時查詢和連接的用戶提供服務。透過跨多個區域(或在多區域部署的情況下為多個區域)運行所有這些元件的多個副本,Cloud Firestore 實現了高可用性和可擴充性。

值得注意的是,所有從行動和 Web SDK 發出的讀取操作都遵循上述模型。它們執行輪詢查詢,然後執行偵聽模式以維持一致性保證。這也適用於即時偵聽器、檢索文件的呼叫和一次性查詢。您可以將單一文件檢索和一次性查詢視為短暫的快照偵聽器,它們在效能方面具有類似的限制。

應用擴展即時查詢的最佳實踐

應用以下最佳實踐來設計可擴展的即時查詢。

了解系統中的高寫入流量

本節可協助您了解系統如何回應越來越多的寫入請求。

隨著寫入流量的增加,驅動即時查詢的 Cloud Firestore 變更日誌會自動水平擴充。隨著資料庫寫入速率的增加超出單一伺服器可以處理的範圍,變更日誌將被分割到多個伺服器上,並且查詢處理開始使用來自多個訂閱處理程序而不是一個訂閱處理程序的資料。從客戶端和 SDK 的角度來看,這都是透明的,發生分割時應用程式不需要採取任何操作。下圖示範了即時查詢如何擴展:

變更日誌扇出的架構

自動縮放可讓您無限制地增加寫入流量,但隨著流量的增加,系統可能需要一些時間來回應。請遵循5-5-5 規則的建議以避免建立寫入熱點。 Key Visualizer是分析寫入熱點的有用工具。

許多應用程式都有可預測的自然成長,Cloud Firestore 可以在不採取預防措施的情況下適應這種成長。然而,批量工作負載(例如匯入大型資料集)可能會使寫入速度過快。在設計應用程式時,請注意寫入流量的來源。

了解寫入和讀取如何交互

您可以將即時查詢系統視為連接寫入操作和讀取器的管道。每當建立、更新或刪除文件時,變更都會從儲存系統傳播到目前註冊的偵聽器。 Cloud Firestore 的變更日誌結構可保證強一致性,這表示您的應用程式永遠不會收到與資料庫提交資料變更時相比無序的更新通知。這透過消除資料一致性的邊緣情況來簡化應用程式開發。

這種連接的管道意味著導致熱點或鎖爭用的寫入操作可能會對讀取操作產生負面影響。當寫入操作失敗或遇到限制時,讀取可能會停止等待變更日誌中的一致資料。如果您的應用程式中發生這種情況,您可能會看到寫入操作緩慢以及相關的查詢回應時間緩慢。避免熱點是避免這個問題的關鍵。

保持文件和寫入操作較小

當使用快照偵聽器建立應用程式時,您通常希望使用者快速發現資料變更。為了實現這一目標,請盡量把事情做得很小。系統可以非常快速地將包含數十個欄位的小型文件推送到系統中。包含數百個欄位和大量資料的較大文件需要更長的時間來處理。

同樣,支援短、快速的提交和寫入操作以保持較低的延遲。從編寫者的角度來看,大批量可能會為您提供更高的吞吐量,但實際上可能會增加快照偵聽器的通知時間。與使用其他資料庫系統(您可能使用批次來提高效能)相比,這通常是違反直覺的。

使用高效的聽眾

隨著資料庫寫入速率的增加,Cloud Firestore 將資料處理分散到許多伺服器上。 Cloud Firestore 的分片演算法嘗試將相同集合或集合群組中的資料共同定位到相同變更日誌伺服器上。系統嘗試最大化可能的寫入吞吐量,同時保持查詢處理中涉及的伺服器數量盡可能少。

但是,某些模式仍可能導致快照偵聽器的行為不理想。例如,如果您的應用程式將大部分資料儲存在一個大型集合中,則偵聽器可能需要連接到許多伺服器才能接收所需的所有資料。即使您套用查詢過濾器,情況仍然如此。連接到許多伺服器會增加響應速度變慢的風險。

為了避免這些較慢的回應,請設計您的架構和應用程序,以便系統可以為偵聽器提供服務,而無需訪問許多不同的伺服器。將資料分成具有較小寫入速率的較小集合可能效果最好。

這類似於考慮關係資料庫中需要全表掃描的效能查詢。在關聯式資料庫中,需要全表掃描的查詢相當於監視高變動集合的快照偵聽器。與資料庫可以使用更具體的索引提供的查詢相比,它的執行速度可能會很慢。具有更具體索引的​​查詢就像一個快照偵聽器,用於監視更改頻率較低的單一文件或集合。您應該對應用程式進行負載測試,以最好地了解用例的行為和需求。

保持快速輪詢查詢

響應式即時查詢的另一個關鍵部分涉及確保引導資料的輪詢查詢快速且有效率。新快照偵聽器第一次連接時,偵聽器必須載入整個結果集並將其傳送至使用者的裝置。緩慢的查詢會降低您的應用程式的回應速度。例如,這包括嘗試讀取許多文件的查詢或不使用適當索引的查詢。

在某些情況下,偵聽器也可能從偵聽狀態返回輪詢狀態。這會自動發生,並且對 SDK 和您的應用程式是透明的。以下情況可能會觸發輪詢狀態:

  • 由於負載變化,系統會重新平衡變更日誌
  • 熱點會導致資料庫寫入失敗或延遲。
  • 短暫的伺服器重新啟動會暫時影響偵聽器。

如果您的輪詢查詢夠快,輪詢狀態對於應用程式的使用者來說就會變得透明。

青睞長壽的聽眾

開啟偵聽器並使偵聽器盡可能長時間地保持活動狀態通常是建立使用 Cloud Firestore 的應用程式最經濟有效的方法。使用 Cloud Firestore 時,您需要為返回應用程式的文件付費,而不是為維護開放連線付費。長期快照偵聽器在其整個生命週期中僅讀取為查詢提供服務所需的資料。這包括初始輪詢操作,然後在資料實際變更時發出通知。另一方面,一次性查詢會重新讀取自應用程式上次執行查詢以來可能未更改的資料。

如果您的應用程式必須消耗高速率的數據,則快照偵聽器可能不合適。例如,如果您的用例在較長一段時間內透過連線每秒推送許多文檔,那麼最好選擇以較低頻率執行的一次性查詢。

下一步是什麼