在 Firebase 即時資料庫中優化效能和擴展資料的最佳方法是將資料拆分到多個即時資料庫實例,也稱為資料庫分片。除了負載平衡和效能最佳化之外,分片還可讓您靈活地擴展到超出適用於單一資料庫執行個體的限制。
何時對數據進行分片
如果您使用即時資料庫並符合以下任一場景,您可能會想要將資料分片到多個資料庫:
- 您希望擴展到超過 200,000 個並發連接、每秒 1,000 個寫入作業的限製或單一資料庫實例的任何其他限制。
- 您有多個離散的資料集,並且想要最佳化效能(例如,為單獨的獨立使用者群組提供服務的聊天應用程式)。
- 您希望平衡多個資料庫之間的負載,以提高正常運作時間並降低單一資料庫執行個體過載的風險。
如何對數據進行分片
若要對資料進行分片,請依照以下步驟操作(以下將詳細介紹):
- 根據應用程式的特定需求將資料對應到多個資料庫。
- 建立多個資料庫實例。
- 配置您的應用程序,使其連接到每個資料集所需的即時資料庫實例。
映射您的數據
當您將資料對應到多個資料庫時,請嘗試滿足以下條件:
- 每個查詢僅針對單一資料庫實例執行。即時資料庫不支援跨資料庫實例的查詢。
- 跨資料庫執行個體不共享或重複資料(或最少共享或重複)。
- 每個應用程式實例在任何給定時刻僅連接到一個資料庫。
在映射資料時,請考慮應用以下策略:
創建“主碎片”
儲存資料在資料庫實例之間儲存方式的對應。這樣,您可以以程式設計方式尋找與連線客戶端相對應的資料庫實例。請記住,這可能比在需要時直接連接到您需要的特定資料庫執行個體產生更多開銷。
按類別或客戶儲存數據
將資料儲存在孤立的資料庫執行個體中,並按使用者或資料類型分組。例如,如果您建立一個為多個組織提供服務的聊天應用程序,則可以為每個組織建立一個資料庫實例,並將所有聊天資料儲存在唯一的資料庫實例中。
在這種情況下,組織 A 和組織 B 不共享數據,資料庫中沒有任何重複數據,而且您僅對單一資料庫執行個體執行查詢。此外,每個組織中的使用者僅在使用聊天應用程式時連接到其組織的資料庫。
然後,您可以提前建立多個資料庫實例,並使用組織的 ID 將團隊對應到其資料庫實例。例如,組織 A 會對應到即時資料庫 A。
為應用程式映射資料的方式取決於您的特定用例,但上面概述的條件和策略可以幫助您定義適合您的資料的方法。
建立多個即時資料庫實例
如果您採用Blaze 定價計劃,則可以在同一 Firebase 專案中最多建立 1,000 個資料庫實例。
- 在 Firebase 控制台中,前往「開發」>「資料庫」部分中的「資料」標籤。
- 從即時資料庫部分的選單中選擇建立新資料庫。
- 自訂您的資料庫參考和安全性規則,然後按一下「知道了」 。
重複此過程以建立所需數量的資料庫實例。每個資料庫執行個體都有自己的一組 Firebase 即時資料庫安全性規則,因此您可以微調對資料的存取。
您可以在 Firebase 控制台中或使用即時資料庫管理 REST API建立和管理資料庫實例。
為每個實例編輯和部署即時資料庫安全性規則
確保您的即時資料庫安全規則允許對專案中的每個資料庫執行個體進行適當的存取。每個資料庫都有自己的一組規則,您可以從 Firebase 控制台編輯和部署這些規則,或使用Firebase CLI 部署目標。
若要從 Firebase 控制台編輯和部署規則,請依照下列步驟操作:
- 轉到“開發”>“資料庫”部分中的“規則”選項卡。
- 選擇要編輯的資料庫,然後修改規則。
若要從 Firebase CLI 編輯和部署規則,請執行下列步驟:
- 修改資料庫實例的規則檔案中的規則(例如
foo.rules.json
)。 - 建立並套用部署目標來關聯使用相同規則檔案的資料庫。例如:
firebase target:apply database main my-db-1 my-db-2
firebase target:apply database other my-other-db-3
使用部署目標更新
firebase.json
設定檔:{ "database": [ {"target": "main", "rules": "foo.rules.json"}, {"target": "other", "rules": "bar.rules.json"} ] }
執行部署指令:
firebase deploy
- 修改資料庫實例的規則檔案中的規則(例如
確保您在同一位置一致地編輯和部署規則。從 Firebase CLI 部署規則會覆寫您在 Firebase 控制台中所做的任何編輯,直接在 Firebase 控制台中編輯規則會覆寫您最近透過 Firebase CLI 部署的任何變更。
將您的應用程式連接到多個資料庫實例
使用資料庫引用存取輔助資料庫執行個體中儲存的資料。您可以透過 URL 或應用程式取得特定資料庫執行個體的參考。如果您不指定 URL,您將獲得對應用程式預設資料庫執行個體的參考。
Web modular API
import { initializeApp } from "firebase/app"; import { getDatabase } from "firebase/database"; const app1 = initializeApp({ databaseURL: "https://testapp-1234-1.firebaseio.com" }); const app2 = initializeApp({ databaseURL: "https://testapp-1234-2.firebaseio.com" }, 'app2'); // Get the default database instance for an app1 const database1 = getDatabase(app1); // Get a database instance for app2 const database2 = getDatabase(app2);
Web namespaced API
const app1 = firebase.initializeApp({ databaseURL: "https://testapp-1234-1.firebaseio.com" }); const app2 = firebase.initializeApp({ databaseURL: "https://testapp-1234-2.firebaseio.com" }, 'app2'); // Get the default database instance for an app1 var database1 = firebase.database(); // Get a database instance for app2 var database2 = firebase.database(app2);
迅速
// Get the default database instance for an appvar ref: DatabaseReference! ref = Database.database().reference()// 透過 URL 取得輔助資料庫實例 var ref: DatabaseReference! ref = Database.database("https://testapp-1234.firebaseio.com").reference()
Objective-C
// Get the default database instance for an app@property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase database] reference];// 透過 URL 取得輔助資料庫實例 @property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase databaseWithURL:@"https://testapp-1234.firebaseio.com"] 參考];
Kotlin+KTX
// Get the default database instance for an app val primary = Firebase.database.reference // Get a secondary database instance by URL val secondary = Firebase.database("https://testapp-1234.firebaseio.com").reference
Java
// Get the default database instance for an app DatabaseReference primary = FirebaseDatabase.getInstance() .getReference(); // Get a secondary database instance by URL DatabaseReference secondary = FirebaseDatabase.getInstance("https://testapp-1234.firebaseio.com") .getReference();
使用 Firebase CLI 時指定實例
使用--instance
選項指定要將 Firebase CLI 指令套用到的 Firebase 即時資料庫。例如,使用下列指令為名為my-example-shard.firebaseio.com
的資料庫實例執行探查器:
firebase database:profile --instance "my-example-shard"
優化每個資料庫上的連接
如果每個用戶端在會話期間需要連接到多個資料庫,您可以透過僅在必要時連接到每個資料庫實例來減少同時連接到每個資料庫實例的數量。
獲得更多建議
如果您需要更多協助來跨多個資料庫實例分片數據,請聯絡我們的Slack 頻道或Stack Overflow上的 Firebase 專家。