大規模瞭解即時查詢

請參閱這份文件,瞭解如何將無伺服器應用程式擴充至每秒數千個作業或數十萬個並行使用者。本文件包含進階主題,可協助您深入瞭解系統。如果您剛開始使用 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 時,您只需為傳回至應用程式的文件付費,而非為維持開放連線付費。長效快照事件監聽器只會讀取在整個生命週期中用於服務查詢所需的資料。這包括初始的輪詢作業,以及在資料實際變更時發出的通知。另一方面,單一讀取查詢會重新讀取自應用程式上次執行查詢後,可能未變更的資料。

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

後續步驟