Cloud Firestore 的最佳做法

請快速參考本文列出的最佳做法 以建構使用 Cloud Firestore 的應用程式

資料庫位置

建立資料庫執行個體時,請選取最靠近使用者和運算資源的資料庫位置。網路跳躍範圍越廣,發生錯誤的機率就越高,查詢延遲時間也會增加。

為了讓 並選取多區域位置 請將重要的運算資源置於至少兩個區域

選取區域位置可降低成本,如果應用程式對延遲時間較為敏感,則可縮短寫入延遲時間,或是與其他 GCP 資源共置

文件 ID

  • 請避免使用文件 ID ...
  • 請勿在文件 ID 中使用 / 斜線。
  • 請勿使用單調遞增的文件 ID,例如:

    • Customer1Customer2Customer3...
    • Product 1Product 2Product 3、...

    這種依序 ID 可能會導致熱點影響延遲時間。

欄位名稱

  • 請避免在欄位名稱中使用以下字元,因為這些字元需要額外逸出:

    • .
    • [ 左括號
    • ] 右方括號
    • * 個星號
    • ` 個倒引號

索引

減少寫入延遲時間

造成寫入延遲的主要原因是索引分支。減少索引分支的最佳做法如下:

  • 組合 集合層級索引豁免設定。最簡單的預設設定是停用「遞減」與陣列索引。移除未使用的索引值也會降低儲存空間費用

  • 減少交易中的文件數量。寫大量時適用 不妨考慮使用大量撰寫工具,不要使用整體化的批次 。

索引豁免情況

對於大多數應用程式,您可以使用自動建立索引功能,以及任何錯誤訊息連結來管理索引。不過,我們建議您 單一欄位豁免項目 下列情況:

案件 說明
大型字串欄位

如果您有一個字串欄位,經常儲存您不會用於查詢的長字串值,您可以將該欄位排除在索引之外,藉此節省儲存空間成本。

寫入含有序列值的集合速度過快

如果您為集合中的文件建立索引,以便在這些文件之間依序增加或減少某個欄位 (例如時間戳記),則集合的寫入頻率上限為每秒 500 次。如果您不根據含有序列值的欄位執行查詢,可以將該欄位豁免 藉此略過這項限制

舉例來說,在寫入頻率高的 IoT 用途中,包含有時間戳記欄位的文件集合可能會接近每秒 500 次寫入的限制。

存留時間欄位

如果使用存留時間 (存留時間) 政策,請留意存留時間 欄位必須為時間戳記。存留時間欄位的索引功能預設為啟用,且 可以在流量率提高的情況下對效能造成影響最佳做法是 保留存留時間欄位的單一欄位豁免情況。

大型陣列或對應欄位

大型陣列或對應欄位可能會接近每個文件 40,000 個索引項目的上限。如果您不是根據大型陣列或對應欄位進行查詢,請將該欄位排除在索引之外。

讀取和寫入作業

  • 應用程式更新單一文件的確切最大速率,取決於工作負載。如需更多資訊 請參閱單一文件更新

  • 盡可能以非同步呼叫取代同步呼叫。 非同步呼叫可以盡可能降低延遲造成的衝擊。以需要文件查詢結果和查詢結果才能顯示回應的應用程式為例。若查詢和查詢沒有資料依附性, 不需要同步等待查詢完成 起始查詢。

  • 不可使用位移,而是改用 遊標。僅使用偏移量可避免 將略過的文件傳回應用程式 仍會擷取到內部 IP 位址系統略過的文件會影響 而且應用程式就要收取讀取作業的費用 擷取。

交易重試

Cloud Firestore SDK 和用戶端 程式庫自動重試失敗 處理暫時性錯誤如果應用程式是透過 RESTRPC API 直接存取 Cloud Firestore,而非透過 SDK,則應實作交易重試功能,以提高可靠性。

即時更新

如需即時更新的最佳做法,請參閱 大規模瞭解即時查詢

資源調度設計

以下最佳做法說明如何避免產生競爭問題的情況。

更新單一文件

設計應用程式時,請考慮應用程式更新單一文件的速度。 評估工作負載效能的最佳方式是執行負載 進行測試。應用程式可更新單一文件的確切頻率上限 會完全視工作負載而定這些因素包括寫入率、請求之間的爭用情形,以及受影響的索引數量。

文件寫入作業會更新文件和任何相關聯的索引, 和 Cloud Firestore 會將寫入作業同步套用到 也就是備用資源當寫入速率過高時,資料庫就會開始發生爭用、延遲時間變長或其他錯誤。

高速讀取、寫入及刪除小範圍文件

請避免高速讀取或寫入字母順序接近的文件,否則應用程式會發生爭用錯誤。此問題稱為資源使用率不均,如果您的應用程式執行以下任一操作,就可能會發生此問題:

  • 極高的速度建立新文件,並自行分配單純增加的 ID。

    Cloud Firestore 會使用散佈演算法分配文件 ID。個人中心 如果您使用 自動產生的文件 ID。

  • 在文件數量不多的集合中,以極高的速度建立新文件。

  • 會以單調遞增的欄位建立新文件,例如 相當高的時間戳記

  • 以高速刪除集合中的文件。

  • 以極高的速度寫入資料庫,但不逐漸增加流量。

避免略過已刪除的資料

避免跳過近期刪除的資料。查詢時可能需要略過 如果早期的查詢結果近期 已刪除。

以工作負載為例,可能需要略過大量刪除的資料 嘗試找出最舊佇列中的工作項目查詢看起來可能會像這樣:

docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
delete_batch.commit()

每次執行此查詢時,系統都會掃描該查詢的索引項目 「created」欄位。這會減緩查詢的速度。

如要提升效能,請使用 start_at 方法找出最佳 。例如:

completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
    {'created': completed_items.get('last_completed')}).order_by(
        'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
  last_completed = doc.get('created')

if last_completed:
  delete_batch.update(completed_items.reference,
                      {'last_completed': last_completed})
  delete_batch.commit()

注意:上述範例使用單調增加的欄位,是高寫入速率的反模式。

增加流量

您應該逐漸增加傳送至新集合或字典順序相近文件的流量,讓 Cloud Firestore 有足夠時間為流量增加做好準備。建議您一開始傳送至新集合的流量不要超過每秒 500 項作業,接著每 5 分鐘增加 50% 的流量。您也可以同樣提高寫入流量 Cloud Firestore 標準限制。請務必 將作業平均分配到索引鍵範圍內。這就是所謂的「500/50/5」規則。

將流量遷移至新的集合

如果您將應用程式流量從某個版本遷移,漸進式提高幅度就特別重要 移至其他集合處理這項遷移作業的簡單方法,就是從舊集合中讀取資料,如果該文件不存在,則從新集合中讀取。但這可能會使得 按照字母順序關閉新集合中的文件。Cloud Firestore 可能無法有效地為新集合準備流量增加的情況,尤其是當集合中包含的文件不多時。

如果您變更同一個集合中多份文件的文件 ID,也會發生類似的問題。

將流量遷移至新集合的最佳策略取決於您的資料 模型以下所舉的策略範例稱為「平行讀取」。您需要判斷這項策略是否適用於您的資料,而平行作業在移轉階段對成本造成的影響會是相當重要的考量因素。

平行讀取

如要在將流量遷移至新集合時實作平行讀取,請參閱 先參考舊的珍藏內容如果文件遺失,請從新的集合讀取。大量讀取不存在的文件可能會造成 因此,請務必逐步增加新的 集合。比較好的策略是將舊文件複製到新集合,然後刪除舊文件。逐漸增加平行讀取,確保 Cloud Firestore 能處理新集合的流量。

要逐漸增加新集合的讀取或寫入,可行策略之一是使用決定性的使用者 ID 雜湊隨機選取嘗試寫入新文件的使用者百分比。請務必避免函式或使用者行為扭曲使用者 ID 雜湊結果。

同時,請執行批次工作,將舊文件中的所有資料複製到新集合。批次工作應避免寫入連續文件 ID,以避免資源使用率不均。批次工作完成後,您就只能讀取新集合。

這個策略的變革是一次只遷移一批使用者。 在使用者文件中新增欄位,用於追蹤該使用者的遷移狀態。 根據使用者 ID 的雜湊碼選取一批使用者。使用批次工作為該批使用者遷移文件,並在遷移期間為使用者使用平行讀取。

請注意,除非您在移轉階段同時寫入新舊實體,否則無法輕易復原。這樣一來, 已產生 Cloud Firestore 費用。

隱私權

  • 避免將機密資訊儲存在 Cloud 專案 ID 中。專案結束後,專案 ID 仍有可能保留下來。
  • 為遵守資料法規,我們建議您不要在文件名稱和文件欄位名稱中儲存機密資訊。

防止未經授權的存取

使用 Cloud Firestore Security Rules 防止未經授權的資料庫作業。舉例來說,使用規則即可避免 惡意使用者重複下載整個資料庫。

進一步瞭解如何使用 Cloud Firestore Security Rules