大規模瞭解即時查詢

請參閱這份文件,瞭解如何將無伺服器應用程式擴充至每秒數千個作業或數十萬個並發使用者。本文提供進階主題,可協助您深入瞭解系統。如果您剛開始使用 Cloud Firestore,請改為參閱快速入門指南

Cloud Firestore 和 Firebase 行動版/網路 SDK 針對開發無伺服器應用程式提供強大的模型,可讓用戶端程式碼直接存取資料庫。SDK 可讓用戶端即時監聽資料更新。您可以使用即時更新功能,建構不需要伺服器基礎架構的回應式應用程式。雖然啟用並執行服務很簡單,但瞭解構成 Cloud Firestore 的系統中的限制條件,有助於讓無伺服器應用程式在流量增加時,能順利擴充及維持良好效能。

如需有關擴充應用程式的建議,請參閱下列各節。

選擇距離使用者較近的資料庫位置

下圖說明即時應用程式的架構:

即時應用程式架構範例

當在使用者裝置 (行動裝置或網頁) 上執行的應用程式建立與 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 使用快照事件監聽器,監聽同一個集合中的更新。每當有人建立新訊息時,Client B 就會立即收到通知。下圖顯示快照事件監聽器背後的架構:

快照事件監聽器連線的架構

當用戶端 B 將快照事件監聽器連線至資料庫時,會發生下列事件序列:

  1. 用戶端 B 會透過 Firebase SDK 呼叫 onSnapshot(collection("chatroom")),開啟至 Cloud Firestore 的連線,並註冊事件監聽器。這個事件監聽器可持續運作數小時。
  2. Cloud Firestore 前端會查詢基礎儲存系統,以啟動資料集。會載入相符文件的整個結果集。我們將這類查詢稱為輪詢查詢。接著,系統會評估資料庫的 Firebase 安全性規則,確認使用者是否可存取這類資料。如果使用者已獲得授權,資料庫就會將資料傳回給使用者。
  3. 接著,用戶端 B 的查詢會進入監聽模式。監聽器會向訂閱處理常式註冊,並等待資料更新。
  4. 用戶端 A 現在會傳送寫入作業來修改文件。
  5. 資料庫會將文件變更內容提交至儲存系統。
  6. 在交易中,系統會將相同更新內容提交至內部變更記錄。變更記錄會在變更發生時以嚴格的順序排列。
  7. 變更記錄會將更新的資料分散到訂閱處理常值集區。
  8. 系統會執行反向查詢比對器,查看更新的文件是否與目前已註冊的快照事件監聽器相符。在本例中,文件會與用戶端 B 的快照事件監聽器相符。顧名思義,您可以將反向查詢比對器視為一般資料庫查詢,但以反向方式執行。這項功能不會搜尋文件,而是針對查詢內容進行有效搜尋,找出與傳入文件相符的內容。找到相符項目時,系統會將相關文件轉送至快照事件監聽器。接著,系統會評估資料庫的 Firebase 安全性規則,確保只有獲授權的使用者才能收到資料。
  9. 系統會將文件更新轉送至用戶端 B 裝置上的 SDK,並觸發 onSnapshot 回呼。如果啟用本機持久性,SDK 也會將更新套用至本機快取。

Cloud Firestore 擴充能力的重要部分,取決於從變更記錄排出、傳遞到訂閱處理常式和前端伺服器。扇形展開功能可讓單一資料變更快速傳播,以便為數百萬個即時查詢和已連結的使用者提供服務。藉由在多個區域 (或多區域部署的情況下) 的多個地區執行所有這些元件的許多備用資源,Cloud Firestore 就能實現高可用性和擴充性。

值得一提的是,從行動和網頁 SDK 發出的所有讀取作業都會遵循上述模型。它們會執行輪詢查詢,接著進入監聽模式,以便維持一致性保證。這項限制也適用於即時監聽器、用於擷取文件的呼叫,以及一次性查詢。您可以將單一文件擷取和單一查詢視為短期快照事件監聽器,這些監聽器也有類似的效能限制。

應用即時查詢的最佳做法

請套用下列最佳做法,設計可擴充的即時查詢。

瞭解系統中的高寫入流量

本節將說明系統如何回應寫入要求數量的增加。

隨著寫入流量增加,驅動即時查詢的 Cloud Firestore 變更記錄會自動橫向擴充。當資料庫的寫入率超過單一伺服器可處理的程度,變更記錄會分散至多個伺服器,而查詢處理程序會開始使用多個訂閱處理常式 (而非單一處理常式) 的資料。從用戶端和 SDK 的角度來看,這一切都是透明的,且在分割發生時,應用程式不需要採取任何行動。下圖說明即時查詢的規模:

變更記錄分支架構

自動調整資源配置功能可讓您在不限制的情況下提高寫入流量,但隨著流量增加,系統可能需要一段時間才能回應。請遵循 5-5-5 規則的建議,避免建立寫入熱點。Key Visualizer 是用於分析寫入熱點的實用工具。

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

瞭解寫入和讀取的互動方式

您可以將即時查詢系統視為與讀取者連結寫入作業的管道。每次建立、更新或刪除文件時,變更都會從儲存系統傳播至目前已註冊的事件監聽器。Cloud Firestore 的變更記錄結構可確保強大一致性,也就是說,您的應用程式不會收到與資料庫提交資料變更時間不符的更新通知。這可消除資料一致性的極端情況,簡化應用程式開發作業。

這個連結管道表示,造成熱點或鎖定爭用的寫入作業,可能會對讀取作業造成負面影響。當寫入作業失敗或受到節流限制時,讀取作業可能會停頓,等待變更記錄中的一致資料。如果應用程式發生這種情況,您可能會看到寫入作業速度緩慢,以及查詢的相關回應時間緩慢。避免資源使用率不均是避免這個問題的關鍵。

縮小文件和寫入作業的大小

使用快照事件監聽器建構應用程式時,您通常會希望使用者能快速瞭解資料變更。為達到這一目標,請盡量縮小尺寸。系統可以快速透過系統推送包含數十個欄位的簡短文件。大型文件含有數百個欄位和大型資料,處理時間會較長。

同樣地,請盡量採用短時間內完成的快速提交和寫入作業,以降低延遲時間。從寫入端的角度來看,大批次可能會提高總處理量,但實際上可能會增加快照事件監聽器的通知時間。相較於使用批次處理來改善效能的其他資料庫系統,這通常不符合直覺。

使用效率高的事件監聽器

隨著資料庫的寫入率增加,Cloud Firestore 會將資料處理作業分散至多個伺服器。Cloud Firestore 的資料分割演算法會嘗試將來自相同集合或集合群組的資料,置於相同的變更記錄伺服器。系統會嘗試盡可能提高寫入總處理量,同時盡可能減少與查詢處理相關的伺服器數量。

不過,某些模式仍可能導致快照事件監聽器的行為不如預期。舉例來說,如果應用程式將大部分資料儲存在一個大型集合中,事件監聽器可能需要連線至多個伺服器,才能接收所需的所有資料。即使您套用查詢篩選器,也一樣。連線至多個伺服器會增加回應速度較慢的風險。

為了避免回應速度較慢,請設計結構定義和應用程式,讓系統能夠在不前往多個不同伺服器的情況下提供事件監聽器。將資料拆分為較小且寫入率較低的集合,可能會是最佳做法。

這類似於考量需要完整掃描資料表的關聯資料庫中的效能查詢。在關聯資料庫中,需要完整資料表掃描的查詢,等同於監控高流失率集合的快照事件監聽器。相較於資料庫可以使用更明確索引的查詢,查詢執行速度可能會比較慢。含有較具體索引的查詢就像快照事件監聽器,可監控單一文件或變更頻率較低的集合。您應載入測試應用程式,以便進一步瞭解用途和用途需求。

確保輪詢查詢速度快速

回應式即時查詢的另一個重要部分,是確保用於啟動資料的輪詢查詢快速且有效率。當新的快照事件監聽器首次連線時,事件監聽器必須載入整個結果集,並將結果傳送至使用者的裝置。查詢速度緩慢會導致應用程式反應速度變慢。這包括嘗試讀取許多文件的查詢,或不使用適當索引的查詢。

在某些情況下,事件監聽器也可能會從監聽狀態移回輪詢狀態。這種情況會自動發生,且對 SDK 和應用程式公開透明。下列情況可能會觸發輪詢狀態:

  • 系統會根據負載變更重新平衡變更記錄
  • 無線基地台會導致資料庫寫入失敗或延遲。
  • 暫時性重新啟動伺服器會暫時影響監聽器。

如果輪詢查詢的速度夠快,輪詢狀態就會對應用程式使用者保持透明。

偏好使用長效監聽器

開啟並盡可能讓監聽器保持運作,通常是建構使用 Cloud Firestore 的應用程式最省成本的方式。使用 Cloud Firestore 時,您只需為傳回至應用程式的文件付費,而非為維持開放連線付費。長效快照事件監聽器只會讀取在整個生命週期中用於服務查詢所需的資料。這包括初始的輪詢作業,以及在資料實際變更時發出的通知。另一方面,單一讀取查詢會重新讀取自應用程式上次執行查詢後,可能未變更的資料。

如果應用程式必須耗用大量資料,快照事件監聽器可能就不適用。舉例來說,如果您的用途是透過連線在一段較長的時間內推送許多文件,建議您改用執行頻率較低的一次性查詢。

後續步驟