請快速參考本文列出的最佳做法 以建構使用 Cloud Firestore 的應用程式
資料庫位置
建立資料庫執行個體時,請選取資料庫 最接近使用者和運算資源的位置 遠離的網路躍點較容易出錯,且查詢延遲時間會增加。
為了讓 並選取多區域位置 請將重要的運算資源置於至少兩個區域
選取區域位置,費用較低,寫入作業較低 延遲時間很長 ,與其他 GCP 資源共存。
文件 ID
- 避免使用文件 ID
.
和..
。 - 避免在文件 ID 中使用
/
正斜線。 請勿使用單調遞增的文件 ID,例如:
Customer1
、Customer2
、Customer3
...Product 1
、Product 2
、Product 3
...
這種依序 ID 可能會導致熱點影響延遲時間。
欄位名稱
避免在欄位名稱中使用下列字元,因為這需要額外的字元 逸出:
.
段期間[
左括弧]
右括弧*
個星號`
個倒引號
索引
縮短寫入延遲時間
寫入延遲的主要貢獻者是索引擴散器。最佳做法 索引擴散功能減少的現象如下:
組合 集合層級索引豁免設定。最簡單的預設設定是停用「遞減」與陣列索引。移除未使用的已建立索引值,也會降低儲存空間費用。
減少交易中的文件數量。寫大量時適用 不妨考慮使用大量撰寫工具,不要使用整體化的批次 。
索引豁免情況
大多數應用程式都能仰賴自動索引和所有錯誤訊息運作 管理索引的連結。不過,我們建議您 單一欄位豁免項目 下列情況:
案件 | 說明 |
---|---|
大型字串欄位 | 如果您的字串欄位經常包含長字串值, 無須用於查詢,只要排除該欄位即可降低儲存費用 建立索引 |
集合寫入具有序列值的文件的寫入速度偏高 | 如果您建立索引的欄位數量 然後是時間戳記等 集合每秒 500 次寫入如果您不根據含有序列值的欄位執行查詢,可以將該欄位豁免 藉此略過這項限制 在寫入速率較高的 IoT 用途中,例如,含有時間戳記欄位的文件集合,可能達到每秒 500 次寫入的上限。 |
存留時間欄位 |
如果使用存留時間 (存留時間) 政策,請留意存留時間 欄位必須為時間戳記。存留時間欄位的索引功能預設為啟用,且 可以在流量率提高的情況下對效能造成影響最佳做法是 保留存留時間欄位的單一欄位豁免情況。 |
大型陣列或對應欄位 | 大型陣列或對應欄位可能會達到每份文件 40,000 個索引項目的上限。如果您不是根據大型陣列或對應欄位進行查詢,請讓索引不必進行索引。 |
讀取和寫入作業
應用程式可更新單一文件的確切頻率上限,會因工作負載而異。如需更多資訊 請參閱單一文件更新。
盡可能以非同步呼叫取代同步呼叫。 非同步呼叫能將延遲時間影響降到最低。例如,假設 需要查詢結果和查詢結果 轉譯回應的方式若查詢和查詢沒有資料依附性, 不需要同步等待查詢完成 起始查詢。
不可使用位移,而是改用 遊標。僅使用偏移量可避免 將略過的文件傳回應用程式 仍會擷取到內部 IP 位址系統略過的文件會影響 而且應用程式也須支付讀取作業費用, 擷取。
重試交易
Cloud Firestore SDK 和用戶端 程式庫自動重試失敗 處理暫時性錯誤如果您的應用程式會存取 Cloud Firestore 到 REST 或 遠端程序呼叫 (RPC) API 而不是透過 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 個 並將每秒作業數轉移到新的集合,再將流量增加 50% 每 5 分鐘檢查一次您也可以同樣提高寫入流量 Cloud Firestore 標準限制。請務必 將作業平均分配到索引鍵範圍內。這個 稱為「500/50/5」規則。
將流量遷移至新的集合
如果您將應用程式流量從某個版本遷移,漸進式提高幅度就特別重要 移至其他集合要處理這項遷移作業,最簡單的方法是從 舊的集合,如果該文件不存在, 請從新的集合讀取 集合。但這可能會使得 按照字母順序關閉新集合中的文件。Cloud Firestore 可能無法有效準備新的集合來吸引更多流量 尤其是當文件不多時
變更多份文件的文件 ID 時,也可能會發生類似的問題 同一個集合內
將流量遷移至新集合的最佳策略取決於您的資料 模型下列策略範例稱為「平行讀取」。您需要 判斷這項策略是否適合您的資料,且 重要的考量將是平行運作期間,對成本的影響
平行讀取
如要在將流量遷移至新集合時實作平行讀取,請參閱 先參考舊的珍藏內容如果文件遺失,請讀取 大量讀取不存在的文件可能會造成 因此,請務必逐步增加新的 集合。更好的策略是將舊文件複製到新文件集 然後刪除舊文件逐步增加平行讀取,以確保 Cloud Firestore 可處理新集合的流量。
逐漸增加讀取或寫入新集合的可行策略 使用確定性的使用者 ID 雜湊,從 位使用者嘗試撰寫新文件。確認使用者的結果 ID 雜湊不會因函式或使用者行為而出現偏差。
同時,請執行批次工作,將舊文件中的所有資料複製到 和新的集合批次工作應避免寫入循序文件 以避免資源使用率不均。批次工作完成後,您只能讀取 建立新的集合
這個策略的變革是一次只遷移一批使用者。 在使用者文件中新增欄位,用於追蹤該使用者的遷移狀態。 根據使用者 ID 的雜湊值選取一批要遷移的使用者。使用 批次工作,藉此為這批使用者遷移文件,並使用 平行讀取 。
請注意,除非您同時寫入 和新實體這樣一來, 已產生 Cloud Firestore 費用。
隱私權
- 避免將機密資訊儲存在 Cloud 專案 ID 中。專案結束後,專案 ID 仍有可能保留下來。
- 為遵循資料法規,我們建議不要將機密資料儲存在 文件名稱和文件欄位名稱中的資訊。
防範未經授權的存取行為
運用以下功能,避免資料庫發生未經授權的作業: Cloud Firestore Security Rules。舉例來說,使用規則即可避免 惡意使用者重複下載整個資料庫。
進一步瞭解如何使用 Cloud Firestore Security Rules。