Implementazione della multitenancy in Spanner

Questo documento descrive vari modi per implementare la multitenancy in Spanner. Descrive inoltre i pattern di gestione dei dati e la gestione del ciclo di vita dei tenant.

La multi-tenancy è quando una singola istanza o alcune istanze di un'applicazione software gestisce più tenant o clienti. Questo pattern software può scalare da un singolo tenant o cliente a centinaia o migliaia. Questo approccio è fondamentale per le piattaforme di cloud computing, in cui l'infrastruttura di base è condivisa tra più organizzazioni.

Pensa all'architettura multi-tenancy come a una forma di partizionamento basato su risorse di calcolo condivise, come i database. Un'analogia sono i tenant di un condominio: infrastruttura condivisa, ma spazio dedicato per i tenant. La multitenancy fa parte della maggior parte delle applicazioni SaaS (Software-as-a-Service) (SaaS), se non tutte.

Questo documento è rivolto agli architect di database, data architect e ingegneri che implementano applicazioni multi-tenant su Spanner come database relazionale. Utilizzando questo contesto, descrive vari approcci per l'archiviazione dei dati multi-tenant. I termini "tenant", "cliente" e "organizzazione" vengono utilizzati in modo intercambiabile nell'articolo per indicare l'entità che accede all'applicazione multi-tenant.

Questo articolo utilizza un provider SaaS per le risorse umane (RU) che implementa la sua applicazione multi-tenant su Google Cloud come esempio. Nell'esempio, più clienti del provider SaaS HR devono accedere all'applicazione multi-tenant. Questi clienti sono chiamati tenant.

Spanner è il database di livello enterprise, distribuito e coerente completamente gestito di Google Cloud che combina i vantaggi del modello di database relazionale con la scalabilità orizzontale non relazionale. Spanner ha una semantica relazionale, con schemi, tipi di dati applicati, elevata coerenza, transazioni ACID a più istruzioni e un linguaggio di query SQL che implementa SQL ANSI 2011.

Spanner offre tempi di inattività pari a zero per la manutenzione pianificata o in caso di guasti a livello di regione, con uno SLA (accordo sul livello del servizio) con disponibilità del 99,999%. Supporta le moderne applicazioni multi-tenant, garantendo alta disponibilità e scalabilità. Questo articolo illustra i diversi approcci all'architettura per implementare l'architettura multi-tenancy con Spanner.

Criteri per i criteri di mappatura dei dati dei tenant

In un'applicazione multi-tenant, i dati di ogni tenant sono isolati in uno dei diversi approcci all'architettura nel database Spanner sottostante. L'elenco seguente illustra i diversi approcci all'architettura utilizzati per mappare i dati di un tenant a Spanner:

  • Istanza: un tenant risiede esclusivamente in un'istanza Spanner, con esattamente un database per quel tenant.
  • Database:un tenant risiede in un database in una singola istanza di Spanner contenente più database.
  • Schema: un tenant risiede in tabelle esclusive all'interno di un database e nello stesso database possono trovarsi diversi tenant.
  • Tabella:i dati tenant sono righe nelle tabelle del database. Queste tabelle sono condivise con altri tenant.

I criteri precedenti sono denominati pattern di gestione dei dati e sono discussi in dettaglio nella sezione Pattern di gestione dei dati multi-tenancy. La discussione si basa sui seguenti criteri:

  • Isolamento: il grado di isolamento dei dati in più tenant è una delle considerazioni più importanti per l'architettura multi-tenancy. L'isolamento è determinato dalle scelte fatte per i criteri di altre categorie, ad esempio determinati requisiti normativi e di conformità possono determinare un grado di isolamento maggiore.
  • Agilità: la facilità di onboarding e offboarding per un tenant in relazione alla creazione di un'istanza, un database o una tabella.
  • Operazioni: la disponibilità o la complessità dell'implementazione di operazioni di database e di amministrazione tipiche e specifiche per il tenant, ad esempio operazioni di manutenzione regolare, logging, backup o ripristino di emergenza.
  • Scalabilità: capacità di scalare senza problemi per consentire la crescita futura. La descrizione di ogni pattern contiene il numero di tenant che il pattern può supportare.
  • Prestazioni: la possibilità di allocare risorse esclusive a ciascun tenant, gestire il fenomeno del vicino rumoroso e abilitare prestazioni di lettura e scrittura prevedibili per ogni tenant.
  • Regolamenti e conformità: la capacità di soddisfare i requisiti dei settori e dei paesi altamente regolamentati che richiedono l'isolamento completo delle risorse e delle operazioni di manutenzione. Ad esempio, i requisiti di residenza dei dati per la Francia richiedono che le informazioni che consentono l'identificazione personale siano archiviate fisicamente esclusivamente in Francia.

Ogni pattern di gestione dei dati in relazione a questi criteri è illustrato in dettaglio nella sezione successiva. Utilizza gli stessi criteri quando selezioni un pattern di gestione dei dati per un gruppo specifico di tenant.

Pattern di gestione dei dati multi-tenancy

Le seguenti sezioni descrivono i quattro pattern di gestione dei dati principali: istanza, database, schema e tabella.

Istanza

Per fornire l'isolamento completo, il pattern di gestione dei dati dell'istanza archivia i dati di ogni tenant nella propria istanza e nel proprio database Spanner. Un'istanza di Spanner può avere uno o più database. In questo pattern viene creato un solo database. Per l'applicazione RU di cui abbiamo parlato in precedenza, viene creata un'istanza di Spanner separata con un database per ogni organizzazione del cliente.

Come mostrato nel diagramma seguente, il pattern di gestione dei dati ha un tenant per istanza.

Gli archivi di pattern di gestione dei dati delle istanze ospitano un singolo tenant per istanza.

La presenza di istanze separate per ogni tenant consente di utilizzare progetti Google Cloud separati per raggiungere limiti di attendibilità separati per tenant diversi. Un ulteriore vantaggio è che ogni configurazione dell'istanza può essere scelta in base alla località di ciascun tenant (a livello di regione o multiregionale), ottimizzando la flessibilità e le prestazioni della località.

L'architettura può facilmente scalare a un numero qualsiasi di tenant. I provider SaaS possono creare un numero qualsiasi di istanze nelle regioni desiderate, senza limiti rigidi.

La seguente tabella descrive in che modo il pattern di gestione dei dati dell'istanza influisce su criteri diversi.

Criteri Istanza: un tenant per pattern di gestione dei dati di istanza
Isolamento
  • Massimo livello di isolamento
  • Nessuna risorsa di database condivisa
Agilità
  • L'onboarding e l'offboarding richiedono una configurazione o il dismissione considerevole per:
    • L'istanza Spanner
    • Sicurezza specifica per l'istanza
    • Connettività specifica per l'istanza
  • L'onboarding e l'offboarding possono essere automatizzati tramite IaC (Infrastructure as Code)
Suite operativa
  • Backup indipendenti per ogni tenant
  • Pianificazioni dei backup separate e flessibili
  • Costi operativi più elevati
    • Grande numero di istanze da gestire e mantenere (scalabilità, monitoraggio, logging e ottimizzazione delle prestazioni)
Scalabilità
  • Database a scalabilità elevata
  • Crescita illimitata tramite l'aggiunta di nodi
  • Numero illimitato di tenant
  • Istanza Spanner disponibile per ogni tenant
Prestazioni
  • Ogni tenant in un'istanza separata
  • Nessuna contesa delle risorse
  • Ottimizzazione delle prestazioni e risoluzione dei problemi su misura per ogni tenant
Requisiti normativi e di conformità
  • Archivia i dati in una regione specifica
  • Implementa processi specifici di sicurezza, backup o controllo, come richiesto da aziende o governi

In sintesi, i concetti chiave sono:

  • Vantaggio:livello di isolamento massimo
  • Svantaggio: maggiore overhead operativo

Il pattern di gestione dei dati dell'istanza è più adatto per i seguenti scenari:

  • I tenant diversi si trovano in un'ampia gamma di regioni e hanno bisogno di una soluzione localizzata.
  • I requisiti normativi e di conformità per alcuni tenant richiedono maggiori livelli di protocolli di sicurezza e controllo.
  • Le dimensioni dei tenant variano in modo significativo, pertanto la condivisione delle risorse tra tenant con volumi elevati e a traffico elevato potrebbe causare conflitti e degrado reciproco.

Database

Nel pattern di gestione dei dati del database, ogni tenant risiede in un database all'interno di una singola istanza Spanner. In una singola istanza possono risiedere più database. Se un'istanza non è sufficiente per il numero di tenant, crea più istanze. Questo pattern implica che una singola istanza di Spanner è condivisa tra più tenant.

Spanner ha un limite fisso di 100 database per istanza. Questo limite significa che se il provider SaaS deve scalare oltre 100 clienti, deve creare e utilizzare più istanze di Spanner.

Per l'applicazione RU, il provider SaaS crea e gestisce ogni tenant con un database separato in un'istanza Spanner.

Come mostrato nel diagramma seguente, il pattern di gestione dei dati ha un tenant per database.

Il pattern di gestione dei dati del database ospita un tenant per database.

Il pattern di gestione dei dati del database raggiunge l'isolamento logico a livello di database per i dati di diversi tenant. Tuttavia, poiché si tratta di una singola istanza di Spanner, tutti i database tenant condividono la stessa configurazione regionale e la stessa configurazione di computing e archiviazione sottostante.

La seguente tabella descrive in che modo il pattern di gestione dei dati del database influisce su criteri diversi.

Criteri Database: un tenant per modello di gestione dei dati del database
Isolamento
  • Completa l'isolamento logico a livello di database
  • Risorse di infrastruttura sottostanti condivise
Agilità
  • Richiede la creazione o l'eliminazione del database ed eventuali controlli di sicurezza specifici
  • L'Automation per onboarding e offboarding avviene tramite IaC
Suite operativa
  • Backup indipendenti per ogni tenant
  • Programmazione flessibile
  • Minore overhead operativo rispetto al pattern di istanza
    • Un'istanza da monitorare per un massimo di 100 database
Scalabilità
  • Database a scalabilità elevata
  • Istanze illimitate
  • Consente migliaia di nodi
  • Limite di 100 database per istanza
    • Per ogni 100 tenant, crea una nuova istanza Spanner
Prestazioni
  • Conflitto di risorse tra più database
    • Database distribuiti tra i nodi di istanza Spanner
    • I database condividono l'infrastruttura
  • I vicini rumorosi influiscono sulle prestazioni
Requisiti normativi e di conformità
  • La regione della località deve corrispondere a quella dell'istanza per soddisfare eventuali requisiti normativi specifici di residenza dei dati

In sintesi, i concetti chiave sono:

  • Vantaggio:livello di isolamento più elevato
  • Svantaggio: numero limitato di tenant per istanza; flessibilità per la località

Il pattern di gestione dei dati del database è più adatto per i seguenti scenari:

  • Più clienti risiedono nella stessa residenza dei dati, ad esempio in Francia o nel Regno Unito, e/o sono soggetti alla stessa autorità di regolamentazione.
  • I tenant richiedono la separazione dei dati e il backup/ripristino basati sul sistema, ma vanno bene con la condivisione delle risorse dell'infrastruttura.

Schema

Nel pattern di gestione dei dati dello schema, viene utilizzato un singolo database, che implementa un singolo schema, per più tenant e un set di tabelle separato per i dati di ogni tenant. Queste tabelle possono essere differenziate includendo tenant ID nei nomi delle tabelle come prefisso o suffisso.

Questo pattern di gestione dei dati di utilizzo di un set separato di tabelle per ogni tenant fornisce un livello di isolamento molto inferiore rispetto alle opzioni precedenti (i pattern di gestione di istanze e database). Inoltre, il pattern semplifica l'onboarding: prevede la creazione di nuove tabelle, nonché integrità e indici di riferimento associati.

Un'avvertenza importante è che le autorizzazioni di accesso per Spanner tramite Identity and Access Management (IAM) vengono fornite solo a livello di istanza o database. Non è possibile fornire le autorizzazioni di accesso a livello di tabella. Esiste anche un limite di 5000 tabelle per database. Per molti clienti, questo limite limita l'uso dell'applicazione.

Inoltre, l'utilizzo di tabelle separate per ogni cliente può comportare un grande arretrato delle operazioni di aggiornamento dello schema. La risoluzione di un arretrato di questo tipo richiede molto tempo.

Per l'applicazione RU, il fornitore di SaaS può creare un insieme di tabelle per ogni cliente con tenant ID come prefisso nei nomi delle tabelle, ad esempio customer1_employee, customer1_payroll, customer1_department.

Come mostrato nel diagramma seguente, il pattern di gestione dei dati di schema ha un set di tabelle per ogni tenant.

Il pattern di gestione dei dati dello schema ha un set di tabelle per ogni tenant.

La seguente tabella descrive in che modo il pattern di gestione dei dati dello schema influisce su criteri diversi.

Criteri Schema: un set di tabelle per ogni pattern di gestione dei dati del tenant
Isolamento
  • Basso livello di isolamento
  • Nessuna sicurezza a livello di tabella
Agilità
  • L'onboarding di un cliente è banale
    • Creazione nuove tabelle
    • Crea chiavi e indici associati
  • L'offboarding di un cliente significa l'eliminazione delle tabelle
    • Può avere un impatto negativo temporaneo sulle prestazioni su altri tenant all'interno del database
Suite operativa
  • Nessuna operazione separata per i tenant
  • Backup, monitoraggio e logging devono essere implementati come funzioni applicazioni separate o come script di utilità
Scalabilità
  • Migliaia di nodi
  • Crescita tenant illimitata
  • Un singolo database può avere solo 5000 tabelle
    • Solo numero minimo (5000/<tabelle numeri per tenant>) di tenant in ogni database
    • Se il database supera le 5000 tabelle, aggiungine uno nuovo per i tenant aggiuntivi
Prestazioni
  • È possibile un alto livello di contesa delle risorse
  • Garantisci buone prestazioni progettando separatamente gli indici per ogni insieme di tabelle
Requisiti normativi e di conformità
  • La regione della località deve corrispondere per soddisfare eventuali requisiti normativi specifici relativi alla residenza dei dati
  • L'implementazione di controlli specifici di sicurezza e controllo influisce su tutti i tenant che risiedono

In sintesi, i concetti chiave sono:

  • Vantaggio: l'onboarding è banale
  • Svantaggio: maggiore overhead operativo; nessun controllo di sicurezza a livello di tabella

Il pattern di gestione dei dati dello schema è più adatto per i seguenti scenari:

  • Applicazioni interne destinate a diversi reparti in cui il rigoroso isolamento della sicurezza dei dati non è un problema importante rispetto alla facilità di manutenzione.
  • Applicazioni multi-tenant in cui i dati non richiedono una rigorosa separazione in base a requisiti legali o normativi.

Sebbene sia possibile creare diversi insiemi di tabelle (ogni set rappresenta un tenant) in un database, dal punto di vista del database rappresenta il pattern meno ideale. Il motivo principale è che le tabelle devono seguire convenzioni di denominazione. L'applicazione e qualsiasi strumento di database (ad esempio, strumenti di migrazione di IDE e di schemi) devono comprendere la convenzione di denominazione. Inoltre, se il numero di tabelle è ragionevolmente grande per tenant, il pattern di gestione dei dati di schema non fornisce una scalabilità significativa.

Un approccio migliore è lo spostamento su un solo database per tenant e aumentare il numero di istanze o lo spostamento al pattern di gestione dei dati della tabella.

Tabella

Il pattern di gestione dei dati finale serve più tenant con un set di tabelle comune. Ogni tabella contiene dati relativi a diversi tenant. Questo pattern di gestione dei dati rappresenta un livello estremo di multi-tenancy in cui tutto, dall'infrastruttura allo schema, fino al modello dei dati, è condiviso tra più tenant. All'interno di una tabella, le righe sono partizionate in base alle chiavi primarie, con tenant ID come primo elemento della chiave. Dal punto di vista della scalabilità, Spanner supporta questo pattern al meglio perché può scalare le tabelle senza limitazioni.

Per l'applicazione RU, la chiave primaria della tabella retribuzioni può essere una combinazione di customerID e payrollID.

Come illustrato nel diagramma seguente, il pattern di gestione dei dati delle tabelle ha una tabella per diversi tenant.

Il pattern di gestione dei dati delle tabelle utilizza una tabella per più tenant.

Analogamente al pattern dello schema, l'accesso ai dati nel pattern della tabella non può essere controllato separatamente per tenant diversi. Se utilizzi meno tabelle, le operazioni di aggiornamento dello schema vengono completate più rapidamente quando ogni tenant ha le proprie tabelle di database. In larga misura, questo approccio semplifica onboarding, offboarding e operazioni.

La seguente tabella descrive in che modo il pattern di gestione dei dati delle tabelle influisce su criteri diversi.

Criteri Tabella: una tabella per diversi pattern di gestione dei dati dei tenant
Isolamento
  • Livello di isolamento minimo
  • Nessuna sicurezza a livello di tenant
Agilità
  • Nessuna configurazione richiesta sul lato database durante l'onboarding
    • L'applicazione può scrivere dati direttamente nelle tabelle esistenti
  • L'offboarding significa eliminare le righe del cliente nella tabella
Suite operativa
  • Nessuna operazione separata per i tenant, inclusi backup, monitoraggio e logging
  • Costo minimo o nullo con l'aumento del numero di tenant
Scalabilità
  • Scalabilità fino a migliaia di nodi
  • Può adattarsi a qualsiasi livello di crescita dei tenant
  • Supporta un numero illimitato di tenant
Prestazioni
  • Il pattern funziona bene nel contesto di Spanner
  • L'archiviazione distribuita interna, l'elaborazione e il bilanciamento del carico possono
  • Se gli spazi chiave primaria non sono progettati con attenzione, è possibile un alto livello di contesa delle risorse (vicino rumoroso)
    • Può impedire la contemporaneità e la distribuzione
  • È importante seguire le best practice
  • L'eliminazione dei dati di un tenant potrebbe avere un impatto temporaneo sul carico
Requisiti normativi e di conformità
  • La località deve corrispondere per soddisfare eventuali requisiti normativi specifici di residenza dei dati
  • Il pattern non può fornire il partizionamento a livello di sistema (rispetto all'istanza o al pattern del database)
  • L'implementazione di specifici controlli di sicurezza e controllo influisce su tutti i tenant

In sintesi, i concetti chiave sono:

  • Vantaggio: elevata scalabilità; ha un overhead operativo ridotto
  • Svantaggio: contesa delle risorse elevata; mancanza di controlli di sicurezza per ogni tenant

Questo pattern è più adatto per i seguenti scenari:

  • Applicazioni interne destinate a diversi reparti in cui il rigoroso isolamento della sicurezza dei dati non è un problema importante rispetto alla facilità di manutenzione.
  • Condivisione massima delle risorse per i tenant che utilizzano la funzionalità dell'applicazione di livello gratuito quando si riduce al minimo il provisioning delle risorse.

Pattern di gestione dei dati e gestione del ciclo di vita dei tenant

La tabella seguente confronta i vari pattern di gestione dei dati in tutti i criteri a un livello elevato.

Istanza Database Schema Tabella
Isolamento Completa Completa Bassa Più negative
Agilità Bassa Moderata Moderata Più alta
Facilità di gestione Alta Alta Bassa Bassa
Scala Alta Limitata Potenzialmente molto limitata Alta
Prestazioni* Alta Moderata Moderata Potenzialmente alto
Regolamenti e conformità Più alta Alta Bassa Bassa

* Le prestazioni dipendono fortemente dalla progettazione dello schema e dalle best practice per le query. I valori qui riportati sono solo un'aspettativa media.

I migliori pattern di gestione dei dati per una specifica applicazione multi-tenant sono quelli che soddisfano la maggior parte dei requisiti in base a determinati criteri. Se un determinato criterio non è richiesto, puoi ignorare la riga in cui si trova.

Pattern di gestione dei dati combinati

Spesso, un singolo pattern di gestione dei dati è sufficiente per soddisfare i requisiti di un'applicazione multi-tenant. In questo caso, la progettazione può assumere un solo pattern di gestione dei dati.

Tuttavia, alcune applicazioni multi-tenant richiedono diversi pattern di gestione dei dati contemporaneamente, ad esempio un'applicazione multi-tenant che supporta un livello gratuito, un livello normale e un livello enterprise.

  • Livello gratuito:

    • Deve essere conveniente
    • Deve avere un limite superiore del volume di dati
    • Generalmente supporta funzionalità limitate
    • Il pattern di gestione dei dati delle tabelle è un buon candidato per il livello gratuito.
      • La gestione degli inquilini è semplice
      • Non è necessario creare risorse tenant specifiche o esclusive
  • Livello regolare:

    • Ideale per i clienti paganti che non hanno requisiti di scalabilità o isolamento specifici
    • Il pattern di gestione dei dati dello schema o del database è un buon candidato di livello regolare.
      • Tabelle e indici sono esclusivi per il tenant
      • Il backup è semplice nel pattern di gestione dei dati del database
      • Il backup non è supportato per il pattern di gestione dei dati dello schema
        • Il backup del tenant deve essere implementato come utilità esterna a Spanner
  • Livello Enterprise:

    • Solitamente si tratta di un livello di fascia alta con autonomia completa in ogni aspetto.
    • Il tenant ha risorse dedicate che includono scalabilità dedicata e isolamento completo
    • Il pattern di gestione dei dati dell'istanza è adatto per il livello enterprise

Una best practice consiste nel mantenere diversi pattern di gestione dei dati in database diversi. Sebbene sia possibile combinare diversi pattern di gestione dei dati in un database Spanner, questo rende difficile implementare la logica di accesso e le operazioni del ciclo di vita dell'applicazione.

La sezione Progettazione delle applicazioni illustra alcune considerazioni sulla progettazione delle applicazioni multi-tenant che si applicano quando si utilizza un singolo pattern di gestione dei dati o più pattern di gestione dei dati.

Gestisci il ciclo di vita dei tenant

I inquilini hanno un ciclo di vita. Pertanto, devi implementare le operazioni di gestione corrispondenti all'interno dell'applicazione multi-tenant. Oltre alle operazioni di base di creazione, aggiornamento ed eliminazione dei tenant, prendi in considerazione le seguenti operazioni aggiuntive relative ai dati:

  • Esporta i dati del tenant:

    • Quando si elimina un tenant, è consigliabile esportare prima i dati ed eventualmente rendere disponibile il set di dati.
    • Quando utilizzi il pattern di gestione dei dati della tabella o dello schema, il sistema applicativo multi-tenant deve implementare l'esportazione o mapparla alla funzionalità del database (esportazione del database).
  • Esegui il backup dei dati del tenant:

    • Quando utilizzi il pattern di gestione dei dati dell'istanza o del database ed esegui il backup dei dati per singoli tenant, usa le funzioni di esportazione o backup del database.
    • Quando utilizzi il pattern di gestione dei dati dello schema o della tabella ed esegui il backup dei dati per singoli tenant, l'applicazione multi-tenant deve implementare questa operazione. Il database Spanner non può determinare quali dati appartengono a quale tenant.
  • Sposta i dati del tenant:

    • Lo spostamento di un tenant da un pattern di gestione dei dati a un altro (o lo spostamento di un tenant all'interno dello stesso pattern di gestione dati tra istanze o database) richiede l'estrazione dei dati dal pattern di gestione dei dati della tabella e l'inserimento di questi dati nel pattern di gestione dei dati del database.

    • Mitigare la situazione di un vicino di casa rumoroso è un altro motivo per trasferire gli inquilini.

Progettazione di applicazioni

Quando progetti un'applicazione multi-tenant, implementa la logica di business con conoscenza del tenant. Ciò significa che ogni volta che l'applicazione esegue la logica di business, deve sempre trovarsi nel contesto di un tenant noto.

Dal punto di vista dei database, la progettazione delle applicazioni significa che ogni query deve essere eseguita in base al modello di gestione dei dati in cui risiede il tenant. Le seguenti sezioni evidenziano alcuni dei concetti centrali della progettazione delle applicazioni multi-tenant.

Connessione tenant dinamica e configurazione delle query

La mappatura dinamica dei dati del tenant alle richieste delle applicazioni tenant utilizza una configurazione di mappatura:

  • Per i pattern di gestione dei dati del database o delle istanze, è sufficiente una stringa di connessione per accedere ai dati di un tenant.
  • Per i pattern di gestione dei dati di schema, è necessario determinare i nomi delle tabelle corretti.
  • Per i pattern di gestione dei dati delle tabelle, le query devono essere eseguite sul database. Utilizza i predicati appropriati per recuperare i dati di un tenant specifico.

Un tenant può risiedere in uno qualsiasi dei quattro pattern di gestione dei dati. La seguente implementazione di mappatura gestisce una configurazione della connessione per il caso generale di un'applicazione multi-tenant che utilizza tutti i pattern di gestione dei dati contemporaneamente. Quando un determinato tenant risiede in un unico pattern, alcune applicazioni multi-tenant utilizzano un unico pattern di gestione dei dati per tutti i tenant. Questo caso è trattato implicitamente dal mapping seguente.

Se un tenant esegue la logica di business (ad esempio, un dipendente che accede con il proprio ID tenant), la logica dell'applicazione deve determinare il pattern di gestione dei dati del tenant, la posizione dei dati per un determinato ID tenant e, facoltativamente, la convenzione di denominazione delle tabelle (per il pattern dello schema).

Questa logica dell'applicazione richiede la mappatura dei pattern dal tenant alla gestione dei dati. Nel seguente esempio di codice, connection string fa riferimento al database in cui si trovano i dati del tenant. L'esempio identifica l'istanza Spanner e il database. Per l'istanza e il database del pattern di gestione dei dati, il seguente codice è sufficiente per consentire all'applicazione di connettersi ed eseguire query:

tenant id -> (data management pattern,
             database connection string,
             [table_prefix])

È necessario un design aggiuntivo per i pattern di gestione dei dati dello schema e della tabella.

Pattern di gestione dei dati dello schema

Per il pattern di gestione dei dati dello schema, esistono diversi tenant all'interno dello stesso database. Ogni tenant ha il proprio set di tabelle. Le tabelle sono distinte per nome. A quale tenant appartiene questa tabella deterministica.

Un approccio consiste nell'anteporre l'ID tenant ai nomi delle tabelle; ad esempio, la tabella EMPLOYEE si chiama T356_EMPLOYEE per il tenant con ID 356. L'applicazione deve anteporre a ogni tabella il prefisso Ttenant ID prima di inviare la query al database restituito dalla mappatura.

Un altro approccio è anteporre table_prefix al mapping utilizzato dalla query in modo da trovare le tabelle corrette per un tenant.

È possibile anche un approccio misto: se il pattern di gestione dei dati è il pattern di schema e il prefisso della tabella è vuoto, viene eseguito il mapping predefinito (anteponi i nomi delle tabelle con gli ID tenant).

Pattern di gestione dei dati delle tabelle

È richiesto un design simile per il pattern di gestione dei dati della tabella. Questo schema è uno schema singolo. I dati dei tenant vengono archiviati come righe. Per accedere correttamente ai dati, aggiungi un predicato a ogni query per selezionare il tenant appropriato.

Un approccio per trovare il tenant appropriato consiste nell'aggiungere una colonna denominata TENANT in ogni tabella. Il valore della colonna è tenant ID. Ogni query deve aggiungere un predicato AND TENANT = tenant ID a una clausola WHERE esistente o una clausola WHERE con il predicato AND TENANT = tenant ID.

Per connettersi al database e creare le query appropriate, l'identificatore tenant deve essere disponibile nella logica dell'applicazione. Può essere passato come parametro o archiviato come contesto thread.

Alcune operazioni del ciclo di vita richiedono la modifica della configurazione di mappatura tenant-to-data-management-pattern: ad esempio, quando sposti un tenant tra i pattern di gestione dei dati, devi aggiornare il pattern di gestione dei dati e la stringa di connessione al database. Potresti anche dover aggiornare il prefisso della tabella.

Generazione e attribuzione delle query

Un principio fondamentale delle applicazioni multi-tenant è che più tenant possono condividere una singola risorsa cloud. I precedenti pattern di gestione dei dati rientrano in questa categoria, tranne il caso in cui un singolo tenant viene allocato a una singola istanza Spanner.

La condivisione delle risorse va oltre la condivisione dei dati. Anche il monitoraggio e il logging sono condivisi: ad esempio, nel pattern di gestione dei dati della tabella e nel pattern di gestione dei dati dello schema, tutte le query per tutti i tenant vengono registrate nello stesso audit log.

Se una query viene registrata, il testo della query deve essere esaminato per determinare per quale tenant è stata eseguita la query. Nel pattern di gestione dei dati delle tabelle, devi analizzare il predicato. Nel pattern di gestione dei dati dello schema, devi analizzare uno dei nomi delle tabelle.

Nel pattern di gestione dei dati del database o nel pattern di gestione dei dati dell'istanza, il testo della query non contiene informazioni sul tenant. Per ottenere informazioni sul tenant per questi pattern, devi eseguire una query sulla tabella di mappatura tenant-to-data-management-pattern.

Sarebbe più facile analizzare i log e le query determinando il tenant per una determinata query senza analizzare il testo della query. Un modo per identificare in modo uniforme un tenant per una query in tutti i pattern di gestione dei dati è aggiungere un commento al testo della query che contiene tenant ID e, facoltativamente, un label.

La seguente query seleziona tutti i dati dei dipendenti per il tenant identificato da TENANT 356. Per evitare di analizzare la sintassi SQL e di estrarre l'ID tenant dal predicato, l'ID tenant viene aggiunto come commento. Un commento può essere estratto senza dover analizzare la sintassi SQL.

select * from EMPLOYEE
  -- TENANT 356
  where TENANT = 'T356';

o

select * from T356_EMPLOYEE;
  -- TENANT 356

Con questa progettazione, ogni query eseguita per un tenant viene attribuita a quel tenant, indipendentemente dal pattern di gestione dei dati. Se un tenant viene spostato da un pattern di gestione dei dati a un altro, il testo della query potrebbe cambiare, ma l'attribuzione rimane la stessa nel testo della query.

L'esempio di codice precedente è solo un metodo. Un altro metodo consiste nell'inserire un oggetto JSON come commento, anziché un'etichetta e un valore:

select * from T356_EMPLOYEE;
  -- {"TENANT": 356}

Operazioni del ciclo di vita dell'accesso tenant

A seconda della tua filosofia di progettazione, un'applicazione multi-tenant può implementare direttamente le operazioni del ciclo di vita dei dati descritte in precedenza oppure creare uno strumento di amministrazione dei tenant separato.

Indipendentemente dalla strategia di implementazione, le operazioni del ciclo di vita potrebbero dover essere eseguite senza la logica dell'applicazione in esecuzione contemporaneamente. Ad esempio, durante lo spostamento di un tenant da un pattern di gestione dei dati a un altro, la logica dell'applicazione non può essere eseguita perché i dati non si trovano in un unico database. Quando i dati non si trovano in un unico database, sono necessarie due operazioni aggiuntive dal punto di vista dell'applicazione:

  • Arresto di un tenant: disabilita l'accesso alla logica dell'applicazione, consentendo al contempo le operazioni del ciclo di vita dei dati.
  • Avvio di un tenant: la logica dell'applicazione può accedere ai dati di un tenant, mentre le operazioni del ciclo di vita che potrebbero interferire con la logica dell'applicazione sono disabilitate.

Sebbene non venga utilizzato spesso, l'arresto di emergenza di un tenant potrebbe essere un'altra importante operazione del ciclo di vita. Utilizza questa chiusura quando sospetti una violazione e devi vietare qualsiasi accesso ai dati di un tenant, non solo la logica dell'applicazione, ma anche le operazioni del ciclo di vita. Una violazione può provenire dall'interno o dall'esterno del database.

Deve essere disponibile anche un'operazione corrispondente del ciclo di vita che rimuove lo stato di emergenza. Un'operazione di questo tipo può richiedere l'accesso simultaneo di due o più amministratori per implementare il controllo reciproco.

Isolamento delle applicazioni

I vari pattern di gestione dei dati supportano diversi gradi di isolamento dei dati tenant. Dal livello più isolato (istanza) al livello meno isolato (tabella), sono possibili diversi gradi di isolamento.

Nel contesto di un'applicazione multi-tenant, è necessario prendere una decisione simile sul deployment: tutti i tenant accedono ai propri dati (in pattern di gestione dei dati diversi) utilizzando lo stesso deployment dell'applicazione? Ad esempio, un singolo cluster Kubernetes potrebbe supportare tutti i tenant e, quando un tenant accede ai suoi dati, lo stesso cluster esegue la logica di business.

In alternativa, come nel caso dei pattern di gestione dei dati, tenant diversi potrebbero essere indirizzati a deployment di applicazioni diversi. I tenant di grandi dimensioni potrebbero avere accesso al deployment di un'applicazione in modo esclusivo, mentre i tenant o i tenant più piccoli nel livello gratuito condividono il deployment dell'applicazione.

Anziché abbinare direttamente i pattern di gestione dei dati descritti in questo articolo a pattern di gestione dei dati delle applicazioni equivalenti, puoi utilizzare il pattern di gestione dei dati del database in modo che tutti i tenant condividano un singolo deployment dell'applicazione. È possibile avere il pattern di gestione dei dati del database e tutti questi tenant condividono un singolo deployment dell'applicazione.

La multitenancy è un modello di gestione dei dati nella progettazione delle applicazioni importante, soprattutto quando l'efficienza delle risorse svolge un ruolo fondamentale. Spanner supporta diversi pattern di gestione dei dati, pertanto può essere utilizzato per implementare applicazioni multi-tenant. Grazie all'estrema scalabilità e al livello di SLA rigorosi, Spanner è il database ideale per i deployment di applicazioni multi-tenant di grandi dimensioni.

Passaggi successivi

  • Esplora le architetture di riferimento, i diagrammi e le best practice su Google Cloud. Visita il nostro Cloud Architecture Center.