使用多個資料庫調度資源

如要最佳化 Firebase Realtime Database 的效能並擴充資料,最好的方法是將資料分散到多個 Realtime Database 執行個體,也就是資料庫 sharding。除了負載平衡和效能最佳化之外,資料分割功能還能讓您彈性擴充,不受個別資料庫執行個體的限制。

資料分割時機

如果您使用 Realtime Database,且符合下列任一情境,建議您將資料分割到多個資料庫:

  • 您想擴充單一資料庫執行個體,超過 200,000 個同時連線、每秒 1,000 次寫入作業或其他限制。
  • 您有多個不連續的資料集,且想最佳化效能 (例如,為不同獨立使用者群組提供服務的即時通訊應用程式)。
  • 您想平衡多個資料庫的負載,提高運作時間,並降低單一資料庫執行個體超載的風險。

如何將資料進行 shard 處理

如要將資料進行 shard 處理,請按照下列步驟操作 (詳情請參閱下文):

  1. 根據應用程式的特定需求,將資料對應至多個資料庫。
  2. 建立多個資料庫執行個體。
  3. 設定應用程式,使其連線至每個資料集所需的 Realtime Database 執行個體。

對應資料

將資料對應至多個資料庫時,請盡量滿足下列條件:

  • 每項查詢只會針對單一資料庫執行個體執行。Realtime Database 不支援跨資料庫執行個體查詢。
  • 資料庫執行個體之間不會共用或複製資料 (或盡可能減少共用或複製)。
  • 每個應用程式執行個體在任何特定時刻都只會連線至一個資料庫。

對應資料時,建議採用下列策略:

建立「主要 shard」

儲存資料在資料庫執行個體中的儲存方式對應。這樣一來,您就能透過程式輔助方式,查詢哪個資料庫執行個體對應至連線用戶端。請注意,與在需要時直接連線至所需特定資料庫執行個體相比,這種做法可能會有更多負擔。

依類別或客戶將資料分組

將資料儲存在獨立的資料庫執行個體中,並依使用者或資料類型分組。舉例來說,如果您建構的即時通訊應用程式為多個組織提供服務,可以為每個組織建立資料庫執行個體,並將所有即時通訊資料儲存在專屬的資料庫執行個體中。

在這種情況下,組織 A 和組織 B 不會共用資料,資料庫中不會有任何重複資料,而且您只會對單一資料庫執行個體執行查詢。此外,各組織的使用者在使用即時通訊應用程式時,只會連線至所屬組織的資料庫。

接著,您可以預先建立多個資料庫執行個體,並使用組織 ID 將團隊對應至其資料庫執行個體。例如,組織 A 對應至即時資料庫 A。

應用程式的資料對應方式取決於特定用途,但上述條件和策略可協助您定義適合資料的做法。

建立多個 Realtime Database 執行個體

如果採用 Blaze 定價方案,您可以在同一個 Firebase 專案中建立最多 1,000 個資料庫執行個體。

在 Firebase 控制台的資料庫專區,使用內容選單建立資料庫

  1. 在 Firebase 控制台中,依序前往「Databases & Storage」 >「即時資料庫」 >「Data」分頁標籤。

  2. 從下拉式選單中選取「Create new database」(建立新資料庫)。

  3. 自訂資料庫參照和Security Rules,然後按一下「Got it」(瞭解)。

重複執行這項程序,視需要建立多個資料庫執行個體。每個資料庫執行個體都有專屬的 Firebase Realtime Database Security Rules,因此您可以精細調整資料存取權。

您可以在 Firebase 控制台建立及管理資料庫執行個體,也可以使用即時資料庫管理 REST API。

使用 CLI 管理特定執行個體並與其互動

您可以使用 Firebase CLI 管理特定 Realtime Database 執行個體,並與其互動。

根據預設,CLI 指令會與預設資料庫執行個體互動。不過,您可以使用 --instance DATABASE_NAME 旗標,與「非預設」資料庫執行個體互動。

例如,使用下列指令,為名為 my-example-shard.firebaseio.com 的資料庫執行個體執行分析器:

firebase database:profile --instance "my-example-shard"

下列指令支援 --instance 旗標:

  • firebase database:get
  • firebase database:profile
  • firebase database:push
  • firebase database:remove
  • firebase database:set
  • firebase database:update

編輯並為每個執行個體部署 Realtime Database Security Rules

請確認 Realtime Database Security Rules 允許適當存取專案中的每個資料庫執行個體。每個資料庫都有專屬的一組規則,您可以透過 Firebase 控制台編輯及部署規則,或使用 Firebase CLI 部署目標。

  • 如要透過 Firebase 控制台編輯及部署規則,請按照下列步驟操作:

    1. 在 Firebase 控制台中,依序前往「Databases & Storage」(資料庫和儲存空間) > 「Realtime Database」(即時資料庫) > 「Rules」(規則) 分頁。

    2. 選取要編輯的資料庫,然後修改規則。

  • 如要透過 Firebase CLI 編輯及部署規則,請按照下列步驟操作:

    1. 修改資料庫執行個體規則檔案中的規則 (例如 foo.rules.json)。

    2. 建立及套用部署目標,連結使用相同規則檔案的資料庫。例如:

      firebase target:apply database main my-db-1 my-db-2
      firebase target:apply database other my-other-db-3

    3. 使用部署目標更新 firebase.json 設定檔:

      {
        "database": [
          {"target": "main", "rules": "foo.rules.json"},
          {"target": "other", "rules": "bar.rules.json"}
        ]
      }
      
    4. 執行 deploy 指令:

      firebase deploy

請務必一律在同一個位置編輯及部署規則。從 Firebase CLI 部署規則會覆寫您在 Firebase 控制台中所做的任何編輯,而直接在 Firebase 控制台中編輯規則會覆寫您最近透過 Firebase CLI 部署的任何變更。

將應用程式連結至多個資料庫執行個體

使用資料庫參照,存取儲存在次要資料庫執行個體中的資料。您可以透過網址或應用程式,取得特定資料庫執行個體的參照。如未指定網址,則會取得應用程式預設資料庫執行個體的參照。

Web

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

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);
Swift
注意:這項 Firebase 產品不適用於 App Clip 目標。
// Get the default database instance for an app
var ref: DatabaseReference!

ref = Database.database().reference()
// Get a secondary database instance by URL var ref: DatabaseReference! ref = Database.database("https://testapp-1234.firebaseio.com").reference()
Objective-C
注意:這項 Firebase 產品不適用於 App Clip 目標。
// Get the default database instance for an app
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];
// Get a secondary database instance by URL @property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase databaseWithURL:@"https://testapp-1234.firebaseio.com"] reference];

Kotlin

// 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();

最佳化每個資料庫的連線

如果每個用戶端在工作階段中需要連線至多個資料庫,您可以只在必要時連線至每個資料庫執行個體,減少每個資料庫執行個體的同時連線數量。

取得更多建議

如需進一步瞭解如何將資料分區至多個資料庫執行個體,請前往 Slack 頻道或 Stack Overflow 聯絡 Firebase 專家。