Cloud Firestore(ベータ版)の発表: Firebase と Google Cloud Platform から新しいスケーラブルで、フレキシブルなデータベースを利用できるようになりました。詳しくは、Cloud Firestore のドキュメントをご覧ください。

複数のデータベースでスケールする

Firebase Realtime Database でパフォーマンスを最適化し、データをスケーリングする最善の方法は、データを複数の Realtime Database インスタンスに分割すること(データベース シャーディング)です。シャーディングを行うと、負荷分散やパフォーマンスの最適化だけでなく、個々のデータベース インスタンスに適用される制限を超えてスケーリングできる柔軟性が得られます。

データをシャーディングするタイミング

以下のいずれかのシナリオで Realtime Database を使用している場合は、複数のデータベースにデータをシャーディングすることをおすすめします。

  • 単一のデータベース インスタンスに適用される同時接続数 100,000、1 秒あたり 1,000 回の書き込みオペレーション、またはその他の制限を超えてスケーリングする場合。
  • 独立した複数のデータセットがあり、パフォーマンスを最適化する必要がある場合(たとえば、個別の独立したユーザー グループにサービスを提供するチャットアプリ)。
  • 複数のデータベース間で負荷を分散して稼働率を向上させ、単一のデータベース インスタンスの過負荷リスクを軽減する場合。

データをシャーディングする方法

データをシャーディングする手順は次のとおりです(詳細は後述します)。

  1. アプリ固有のニーズに応じて、複数のデータベースにデータをマッピングします。
  2. 複数のデータベース インスタンスを作成します。
  3. データセットごとに必要な Realtime Database インスタンスに接続するようにアプリを設定します。

データをマッピングする

データを複数のデータベースにマッピングする場合は、以下の条件を満たすようにしてください。

  • 各クエリが、単一のデータベース インスタンスに対してのみ実行されること。Realtime Database では、複数のデータベース インスタンスに対するクエリはサポートされていません。
  • 複数のデータベース インスタンス間でデータの共有や重複が発生しないこと(または共有や重複を最小限に抑えること)。
  • ある時点で、各アプリ インスタンスが 1 つのデータベースだけに接続すること。

データをマッピングする際には、次の戦略を使うことをおすすめします。

「マスター シャード」を作成する

データが複数のデータベース インスタンス間にどのように格納されているかを示すマップを保存します。これにより、接続するクライアントに対応するデータベース インスタンスをプログラムによって検索することができます。ただし、特定のデータベース インスタンスを必要とする場合は、直接接続するよりもオーバーヘッドが増える可能性があることに注意してください。

カテゴリ別または顧客別のバケットデータ

ユーザータイプまたはデータ型でデータベース インスタンスをサイロ化してデータを保存します。たとえば、複数の組織にサービスを提供するチャットアプリを構築する場合は、組織ごとにデータベース インスタンスを作成し、すべてのチャットデータを固有のデータベース インスタンスに格納することができます。

この場合、組織 A と組織 B はデータを共有せず、データベース内に重複データは発生せず、単一のデータベース インスタンスに対してのみクエリが実行されます。さらに、各組織のユーザーがチャットアプリを使用するときは、各自の組織のデータベースだけに接続します。

この場合、あらかじめ複数のデータベース インスタンスを作成しておき、組織の ID を使用して、そのデータベース インスタンスにチームをマッピングすることができます。たとえば、組織 A を Realtime Database A にマッピングします。

アプリのデータをマッピングする方法は、各自のユースケースによって異なりますが、前述の条件は、データに適した定義を行うのに役立ちます。

複数の Realtime Database インスタンスを作成する

Blaze お支払いプランをご利用の場合は、同じ Firebase プロジェクト内に複数のデータベース インスタンスを作成できます。

データベース セクションのコンテキスト メニューを使用して Firebase コンソールにデータベースを作成する

  1. Firebase コンソールで、[Develop] > [Database] セクションの [データ] タブに移動します。
  2. [Database] セクションのメニューから [新しいデータベースを作成] を選択します。
  3. データベース参照セキュリティ ルールをカスタマイズして、[OK] をクリックします。

このプロセスを繰り返して、必要なだけデータベース インスタンスを作成します。各データベース インスタンスには独自の Firebase Realtime Database ルールセットがあり、データへのアクセスを微調整できます。

各インスタンスの Firebase Database ルールの編集とデプロイ

Firebase Database ルールを設定してプロジェクト内の各データベース インスタンスに適切なアクセス権を付与してあることを確認します。各データベースには独自のルールセットがあり、ルールの編集やデプロイは Firebase コンソールから行います。また、デプロイ ターゲットに対する Firebase CLI を使用してルールの編集やデプロイを行うこともできます。

Firebase コンソールからルールを編集してデプロイするには、[Develop] > [Database] セクションの [ルール] タブに移動します。ルールを編集して変更するデータベースを選択します。

Firebase CLI からルールを編集してデプロイする手順は次のとおりです。

  1. 各データベースのデプロイ ターゲットを設定します。同じルールファイルを使用するデータベースをすべて同じターゲットに関連付けます。次に例を示します。
    firebase target:apply database main my-db-1 my-db-2
    firebase target:apply database other my-other-db-3
    
  2. firebase.json を更新してデプロイ ターゲットを追加します。
    {
    "database": [
    {"target": "main", "rules", "foo.rules.json"},
    {"target": "other", "rules": "bar.rules.json"}
    ]
    }
    
  3. deploy コマンドを実行します。
    firebase deploy
    

常に同じ場所からルールを編集してデプロイするようにしてください。Firebase CLI からルールをデプロイすると、Firebase コンソールで行った編集がオーバーライドされ、Firebase コンソールで直接ルールを編集すると、Firebase CLI でデプロイした最新の変更がオーバーライドされます。

アプリを複数のデータベース インスタンスに接続する

セカンダリ データベース インスタンスに保存されているデータにアクセスするには、データベース参照を使用します。特定のデータベース インスタンスの参照は URL またはアプリで取得できます。URL を指定しないと、アプリのデフォルト データベース インスタンスの参照が取得されます。

ウェブ
// Get the default database instance for an app
var database = firebase.database();

// Get a secondary database instance by URL
var database = firebase.database('https://testapp-1234.firebaseio.com');
Swift
// 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
// 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];
Android
// Get the default database instance for an app
private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();

// Get a secondary database instance by URL
private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance("https://testapp-1234.firebaseio.com").getReference();

各データベースの接続を最適化する

セッション中に各クライアントが複数のデータベースに接続する必要がある場合は、必要なときだけ各データベース インスタンスに接続することで、各データベース インスタンスへの同時接続数を減らすことができます。

アドバイスが必要な場合

複数のデータベース インスタンスにわたってデータをシャーディングする処理の詳細については、Slack チャンネルまたは Stack Overflow から Firebase のエキスパートにお問い合わせください。

フィードバックを送信...

Firebase Realtime Database
ご不明な点がありましたら、Google のサポートページをご覧ください。