Scala con più database

Il modo migliore per ottimizzare le prestazioni e scalare i dati in Firebase Realtime Database è suddividerli in più istanze Realtime Database, un processo noto anche come sharding del database. Lo sharding ti offre la flessibilità di scalare oltre i limiti che si applicano alle singole istanze di database, oltre al bilanciamento del carico e all'ottimizzazione delle prestazioni.

Quando eseguire lo sharding dei dati

Se utilizzi Realtime Database, ti consigliamo di eseguire lo sharding dei dati su più database nei seguenti scenari:

  • Vuoi scalare oltre il limite di 200.000 connessioni simultanee, 1000 operazioni di scrittura al secondo o uno qualsiasi degli altri limiti per una singola istanza di database.
  • Hai più set di dati discreti e vuoi ottimizzare le prestazioni (ad esempio, un'app di chat che serve gruppi di utenti separati e indipendenti).
  • Vuoi bilanciare il carico su più database per migliorare l'uptime e ridurre il rischio di sovraccaricare una singola istanza di database.

Come eseguire lo sharding dei dati

Per eseguire lo sharding dei dati, segui questi passaggi (descritti in maggiore dettaglio di seguito):

  1. Mappa i dati su più database in base alle esigenze specifiche della tua app.
  2. Crea più istanze di database.
  3. Configura l'app in modo che si connetta all'istanza Realtime Database necessaria per ogni set di dati.

Mappa i dati

Quando mappi i dati su più database, prova a soddisfare le seguenti condizioni:

  • Ogni query viene eseguita solo su una singola istanza di database. Realtime Database non supporta le query tra istanze di database.
  • Nessuna condivisione o duplicazione dei dati tra le istanze di database (o condivisione o duplicazione minima).
  • Ogni istanza dell'app si connette a un solo database alla volta.

Durante la mappatura dei dati, valuta la possibilità di applicare le seguenti strategie:

Crea uno "shard master"

Archivia una mappa di come i dati vengono archiviati nelle istanze del database. In questo modo, puoi cercare in modo programmatico l'istanza di database corrispondente al client di connessione. Tieni presente che questo potrebbe comportare un overhead maggiore rispetto alla connessione diretta alla particolare istanza di database di cui hai bisogno, quando ne hai bisogno.

Raggruppa i dati per categorie o per cliente

Archivia i dati in istanze di database isolate, raggruppate per utente o tipo di dati. Ad esempio, se crei un'applicazione di chat che serve più organizzazioni, puoi creare un'istanza di database per ogni organizzazione e archiviare tutti i dati della chat in istanze di database univoche.

In questo caso, l'organizzazione A e l'organizzazione B non condividono dati, non sono presenti dati duplicati nei database ed esegui query solo su una singola istanza di database. Inoltre, gli utenti di ciascuna organizzazione si connettono solo al database della propria organizzazione quando utilizzano l'app di chat.

Puoi quindi creare diverse istanze di database in anticipo e utilizzare l'ID dell'organizzazione per mappare un team alla relativa istanza di database. Ad esempio, l'organizzazione A viene mappata a Realtime Database A.

Il modo in cui mappi i dati per la tua app dipende dal tuo caso d'uso specifico, ma le condizioni e le strategie descritte sopra possono aiutarti a definire ciò che funziona per i tuoi dati.

Crea più istanze Realtime Database

Se utilizzi il piano tariffario Blaze, puoi creare fino a 1000 istanze di database nello stesso progetto Firebase.

crea un database nella console Firebase con il menu contestuale nella sezione Database

  1. Nella console Firebase, vai a Database e spazio di archiviazione > Realtime Database > scheda Dati.

  2. Seleziona Crea nuovo database dal menu a discesa.

  3. Personalizza il riferimento al database e Security Rules, quindi fai clic su Ok.

Ripeti la procedura per creare tutte le istanze di database di cui hai bisogno. Ogni istanza di database ha il proprio set di Firebase Realtime Database Security Rules, in modo da poter ottimizzare l'accesso ai dati.

Puoi creare e gestire le istanze di database nella console Firebase o utilizzando l'API REST di gestione di Realtime Database.

Gestisci e interagisci con istanze specifiche utilizzando l'interfaccia a riga di comando

Puoi gestire e interagire con istanze Realtime Database specifiche utilizzando l'interfaccia a riga di comando Firebase.

Per impostazione predefinita, i comandi dell'interfaccia a riga di comando interagiscono con l'istanza di database predefinita. Tuttavia, puoi interagire con un'istanza di database non predefinita utilizzando il flag --instance DATABASE_NAME.

Ad esempio, utilizza il seguente comando per eseguire il profiler per un'istanza di database denominata my-example-shard.firebaseio.com:

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

I seguenti comandi supportano il flag --instance:

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

Modifica ed esegui il deployment di Realtime Database Security Rules per ogni istanza

Assicurati che i tuoi Realtime Database Security Rules consentano l'accesso appropriato a ogni istanza di database nel tuo progetto. Ogni database ha il proprio insieme di regole, che puoi modificare ed eseguire il deployment dalla console Firebase o utilizzando l'interfaccia a riga di comando Firebase per eseguire il deployment delle destinazioni.

  • Per modificare ed eseguire il deployment delle regole dalla console Firebase, segui questi passaggi:

    1. Nella console Firebase, vai a Database e spazio di archiviazione > Realtime Database > scheda Regole.

    2. Seleziona il database da modificare, quindi modifica le regole.

  • Per modificare ed eseguire il deployment delle regole dall'interfaccia a riga di comando Firebase, segui questi passaggi:

    1. Modifica le regole nei file delle regole per le istanze di database (ad esempio foo.rules.json).

    2. Crea e applica target di deployment per associare i database che utilizzano lo stesso file di regole. Ad esempio:

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

    3. Aggiorna il file di configurazione firebase.json con i target di deployment:

      {
        "database": [
          {"target": "main", "rules": "foo.rules.json"},
          {"target": "other", "rules": "bar.rules.json"}
        ]
      }
      
    4. Esegui il comando di deployment:

      firebase deploy

Assicurati di modificare e implementare le regole sempre dallo stesso posto. Il deployment delle regole dall'interfaccia a riga di comando Firebase esegue l'override di tutte le modifiche apportate nella console Firebase, mentre la modifica delle regole direttamente nella console Firebase esegue l'override di tutte le modifiche recenti di cui hai eseguito il deployment tramite l'interfaccia a riga di comando Firebase.

Connetti la tua app a più istanze di database

Utilizza il riferimento al database per accedere ai dati archiviati nelle istanze di database secondarie. Puoi ottenere il riferimento per un'istanza di database specifica tramite URL o app. Se non specifichi un URL, riceverai il riferimento per l'istanza di database predefinita dell'app.

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
Nota:questo prodotto Firebase non è disponibile nel target 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
Nota:questo prodotto Firebase non è disponibile nel target 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();

Ottimizza le connessioni su ogni database

Se ogni client deve connettersi a più database durante una sessione, puoi ridurre il numero di connessioni simultanee a ogni istanza di database connettendoti a ogni istanza di database solo per il tempo necessario.

Ricevi altri consigli

Se hai bisogno di ulteriore assistenza per lo sharding dei dati su più istanze di database, contatta gli esperti di Firebase sul nostro canale Slack o su Stack Overflow.