Implementare la multitenancy in Spanner

Questa pagina descrive vari modi per implementare il multitenancy in Spanner. Vengono inoltre discussi i pattern di gestione dei dati e la gestione del ciclo di vita dei tenant. È destinato ad architetti di database, architetti di dati e ingegneri che implementano applicazioni multi-tenant su Spanner come database relazionale. Utilizzando questo contesto, vengono descritti vari approcci per archiviare dati multi-tenant. I termini "tenant", "cliente" e "organizzazione" vengono utilizzati in modo intercambiabile nell'articolo per indicare l'entità che accede all'applicazione multitenant. Gli esempi forniti in questa pagina si basano sull'implementazione della propria applicazione multi-tenant di un fornitore SaaS di risorse umane (RU) su Google Cloud. Uno dei requisiti è che più clienti del fornitore SaaS RU debbano accedere all'applicazione multi-tenant. Questi clienti sono chiamati tenant.

Multitenancy

La multi-tenancy si verifica quando una singola istanza o poche istanze di un'applicazione software servono più tenant o clienti. Questo pattern software può essere scalato da un singolo tenant o cliente a centinaia o migliaia. Questo approccio è fondamentale per le piattaforme di cloud computing in cui l'infrastruttura sottostante è condivisa tra più organizzazioni.

Considera il multi-tenancy come una forma di partizionamento basata su risorse di calcolo condivise, come i database. Un'analogia è quella degli inquilini di un condominio: gli inquilini condividono l'infrastruttura, come le tubature dell'acqua e le linee elettriche, ma ogni inquilino ha uno spazio dedicato in un appartamento. Il multi-tenancy fa parte della maggior parte, se non di tutte, le applicazioni Software as a Service (SaaS).

Spanner è il database completamente gestito, di livello aziendale, distribuito e coerente di Google Cloudche 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 multi-istruzione e un linguaggio di query SQL che implementa SQL ANSI 2011. Fornisce zero tempi di inattività per la manutenzione pianificata o gli errori di regione, con uno SLA (accordo sul livello del servizio) di disponibilità del 99,999%. Spanner supporta anche applicazioni moderne multi-tenant fornendo alta disponibilità e scalabilità.

Criteri per i criteri di mappatura dei dati del tenant

In un'applicazione multi-tenant, i dati di ogni tenant sono isolati in uno dei diversi approcci di architettura nel database Spanner sottostante. L'elenco seguente descrive 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 un solo database per quel tenant.
  • Database:un tenant si trova in un database in una singola istanza Spanner contenente più database.
  • Tabella:un tenant risiede in tabelle esclusive all'interno di un database e più tenant possono trovarsi nello stesso database.
  • Riga: i dati del tenant sono righe nelle tabelle del database. Queste tabelle sono condivise con altri tenant.

I criteri precedenti sono chiamati pattern di gestione dei dati e sono descritti in dettaglio nella sezione Pattern di gestione dei dati multi-tenant. Questa discussione si basa sui seguenti criteri:

  • Isolamento dei dati:il grado di isolamento dei dati in più tenant è un aspetto fondamentale per il multi-tenancy. Ad esempio, se i dati devono essere separati fisicamente o logicamente e se esistono ACL (elenchi di controllo degli accessi) indipendenti che possono essere impostati per i dati di ogni tenant. L'isolamento è determinato dalle scelte effettuate per i criteri delle altre categorie. Ad esempio, determinati requisiti normativi e di conformità potrebbero richiedere un maggiore grado di isolamento.
  • Agilità: la facilità di onboarding e offboarding delle attività per un tenant rispetto alla creazione di un'istanza, un database, una tabella o una riga.
  • Operazioni:la disponibilità o la complessità dell'implementazione di operazioni di database e attività di amministrazione tipiche e specifiche del tenant. Ad esempio, operazioni regolari di manutenzione, logging, backup o ripristino di emergenza.
  • Scalabilità:la possibilità di scalare senza interruzioni per consentire la crescita futura. La descrizione di ogni pattern contiene il numero di tenant che il pattern può supportare.
  • Prestazioni:
    • Isolamento delle risorse: la possibilità di allocare risorse esclusive a ogni tenant, risolvere il fenomeno del vicino rumoroso e consentire prestazioni di lettura e scrittura prevedibili per ogni tenant.
    • Risorse minime per tenant: la quantità minima media di risorse per tenant. Ciò non significa necessariamente che devi pagare almeno questo importo per ogni singolo inquilino, ma piuttosto che devi pagare almeno N * questo importo per tutti gli N inquilini insieme.
    • Efficienza delle risorse: la possibilità di utilizzare le risorse inattive di altri tenant per risparmiare sui costi complessivi.
    • Selezione della posizione per l'ottimizzazione della latenza: la possibilità di scegliere una topologia di replica specifica per ogni tenant in modo che i dati di ogni tenant possano essere inseriti nella posizione che offre la latenza migliore per il tenant.
  • Normative e conformità:la possibilità di soddisfare i requisiti di settori e 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 vengano archiviate fisicamente solo in Francia. I settori finanziari di solito richiedono chiavi di crittografia gestite dal cliente (CMEK) e ogni tenant potrebbe voler utilizzare la propria chiave di crittografia.

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

Pattern di gestione dei dati multi-tenant

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

Istanza

Per fornire un 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 Spanner può avere uno o più database. In questo pattern, viene creato un solo database. Per l'applicazione RU descritta in precedenza, viene creata un'istanza Spanner separata con un database per ogni organizzazione cliente.

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

Il pattern di gestione dei dati dell'istanza memorizza un singolo tenant per istanza.

Avere istanze separate per ogni tenant consente l'utilizzo di progettiGoogle Cloud separati per ottenere confini di attendibilità separati per tenant diversi. Un ulteriore vantaggio è che ogni configurazione dell'istanza può essere scelta in base alla posizione di ogni tenant (a livello regionale o multiregionale), ottimizzando la flessibilità e le prestazioni della posizione.

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

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

Criteri Istanza: un tenant per pattern di gestione dei dati dell'istanza
Isolamento dei dati
  • Massimo livello di isolamento dei dati
  • L'archiviazione dei dati è fisicamente separata
  • Gli elenchi di controllo dell'accesso vengono concessi separatamente per ogni istanza
Agilità
  • L'onboarding e l'offboarding richiedono una configurazione o un ritiro considerevoli per:
    • L'istanza Spanner
    • Sicurezza specifica dell'istanza
    • Connettività specifica per l'istanza
  • L'onboarding e l'offboarding possono essere automatizzati tramite Infrastructure as Code (IaC).
Operazioni
  • Backup indipendenti per ogni tenant
  • Pianificazioni di backup separate e flessibili
  • Costi operativi più elevati
    • Un numero elevato di istanze da gestire e mantenere (scalabilità, monitoraggio, logging e ottimizzazione delle prestazioni)
Scala
  • Database a scalabilità elevata
  • Crescita illimitata aggiungendo nodi
  • Numero illimitato di tenant
  • Istanza Spanner disponibile per ogni tenant
Prestazioni
  • Isolamento delle risorse: nessuna contesa di risorse
  • Risorse minime per tenant: la risorsa minima per tenant è 1 nodo se utilizzi un'istanza più grande e 100 PU (1/10 dei nodi) se utilizzi un'istanza granulare
  • Efficienza delle risorse: non è possibile utilizzare le risorse inattive di altri tenant
  • Selezione della posizione per l'ottimizzazione della latenza: inserisci ogni tenant in un'istanza separata e personalizza la topologia di replica per ogni tenant
Requisiti normativi e di conformità
  • Archivia i dati in una regione specifica
  • Implementare processi specifici di sicurezza, backup o controllo come richiesto da aziende o governi

In sintesi, i concetti chiave sono:

  • Vantaggio:massimo livello di isolamento
  • Svantaggio: il sovraccarico operativo più elevato e potenzialmente costi maggiori a causa del minimo di 100 PU per tenant. La condivisione delle risorse tra tenant non è supportata.

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

  • Tenant diversi sono distribuiti in un'ampia gamma di regioni e richiedono una soluzione localizzata.
  • I requisiti normativi e di conformità per alcuni tenant richiedono livelli più elevati di sicurezza e protocolli di controllo.
  • Le dimensioni dei tenant variano in modo significativo, pertanto la condivisione delle risorse tra tenant con volumi elevati e traffico elevato potrebbe causare contese 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. Più database possono risiedere in una singola istanza. Se un'istanza non è sufficiente per il numero di tenant, crea più istanze. Questo pattern implica che una singola istanza Spanner sia condivisa tra più tenant.

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

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

Come mostrato nel seguente diagramma, il pattern di gestione dei dati prevede 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 consente di ottenere l'isolamento logico a livello di database per i dati di tenant diversi. Tuttavia, poiché si tratta di una singola istanza Spanner, tutti i database tenant condividono la stessa topologia di replica e la stessa configurazione di calcolo e archiviazione sottostante, a meno che non venga utilizzata la funzionalità di partizionamento geografico. Puoi utilizzare la funzionalità di partizionamento geografico di Spanner per creare partizioni di istanza in posizioni diverse e utilizzare partizioni di istanza diverse per database diversi nella stessa istanza.

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

Criteri Database: un tenant per pattern di gestione dei dati del database
Isolamento dei dati
  • Isolamento logico completo a livello di database
  • L'archiviazione dei dati è fisicamente separata
  • Puoi concedere ACL a tutti i database nell'istanza oppure puoi concederle separatamente a ogni database.
Agilità
  • Richiede impegno per creare o eliminare il database e qualsiasi controllo di sicurezza specifico
  • L'Automation per l'onboarding e l'offboarding avviene tramite Infrastructure as Code (IaC)
Operazioni
  • Backup indipendenti per ogni tenant
  • Pianificazioni di backup separate e flessibili
  • Costi operativi inferiori rispetto al pattern di istanza
    • Un'istanza da monitorare per un massimo di 100 database
Scala
  • Database a scalabilità elevata
  • Limite di 100 database per istanza. Crea una nuova istanza Spanner ogni 100 tenant.
  • Istanze illimitate
  • Numero illimitato di nodi per istanza
Prestazioni
  • Isolamento delle risorse: contesa tra più database
    • Database distribuiti tra i nodi dell'istanza Spanner
    • I database condividono l'infrastruttura
    • I vicini rumorosi influiscono sulle prestazioni
  • Risorse minime per tenant: poiché esiste un limite di 100 database per istanza, la capacità di calcolo minima per 100 database (o 100 tenant) è 1 nodo. Anche per un'istanza granulare, la capacità di calcolo minima per 100 tenant è comunque di 1 nodo. Sebbene ogni istanza granulare possa utilizzare anche solo 100 unità di elaborazione, Spanner consente un limite di 10 database per 100 unità di elaborazione.
  • Uso efficiente delle risorse: i tenant condividono le risorse di un'istanza. I tenant possono utilizzare le risorse inattive di altri tenant.
  • Selezione della posizione per l'ottimizzazione della latenza: se non utilizzi la funzionalità di partizionamento geografico, la posizione del database è la stessa della configurazione dell'istanza. Non puoi personalizzare la posizione del database per ogni tenant. Tuttavia, se utilizzi la funzionalità di partizionamento geografico, puoi creare partizioni dell'istanza in posizioni diverse e puoi inserire i dati in posizioni diverse utilizzando una chiave di posizionamento delle righe. L'utilizzo del partizionamento geografico ottimizza la latenza per ogni tenant.
Requisiti normativi e di conformità
  • Se non utilizzi la funzionalità di partizionamento geografico, la posizione dei database è la stessa della configurazione dell'istanza per soddisfare i requisiti normativi di residenza dei dati. Tuttavia, se utilizzi la funzionalità di partizionamento geografico, puoi creare partizioni di istanze in località diverse e inserire i dati in località diverse utilizzando una chiave di posizionamento per riga.
  • Ogni database può utilizzare la propria CMEK per la crittografia dei dati.

In sintesi, i concetti chiave sono:

  • Vantaggio: livello moderato di isolamento dei dati e delle risorse; livello moderato di efficienza delle risorse; ogni tenant può avere il proprio backup e la propria CMEK.
  • Svantaggio: numero limitato di tenant per istanza; posizione inflessibile se non si utilizza la funzionalità di partizionamento geografico.

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

  • Più clienti si trovano nella stessa residenza dei dati o sono soggetti alla stessa autorità di regolamentazione.
  • I tenant richiedono la separazione dei dati basata sul sistema e la possibilità di eseguire il backup e il ripristino dei propri dati, ma non hanno problemi con la condivisione delle risorse dell'infrastruttura.
  • I tenant richiedono la propria CMEK.
  • Il costo è un fattore importante da considerare. Le risorse minime necessarie per tenant sono inferiori al costo di un'istanza. È auspicabile che i tenant utilizzino le risorse inattive di altri tenant.

Tabella

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

Questo pattern di gestione dei dati che utilizza un insieme 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). L'onboarding prevede la creazione di nuove tabelle e di indici e integrità referenziale associati.

Esiste un limite di 5000 tabelle per database. Per alcuni clienti, questo limite potrebbe limitare l'utilizzo dell'applicazione.

Inoltre, l'utilizzo di tabelle separate per ogni cliente può comportare un grande arretrato di operazioni di aggiornamento dello schema. Un backlog di questo tipo richiede molto tempo per essere risolto.

Per l'applicazione RU, il provider 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 e customer1_department. In alternativa, possono utilizzare l'ID tenant come schema denominato e denominare la tabella come customer1.employee, customer1.payroll e customer1.department.

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

Il pattern di gestione dei dati della tabella ha un insieme di tabelle per ogni tenant.

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

Criteri Tabella: un insieme di tabelle per ogni pattern di gestione dei dati del tenant
Isolamento dei dati
  • Livello moderato di isolamento dei dati. I dati sono separati logicamente, ma possono essere archiviati fisicamente nello stesso file sull'archiviazione permanente.
  • Gli ACL vengono condivisi per impostazione predefinita, ma possono essere concessi separatamente utilizzando il controllo dell'controllo dell'accesso granulare (FGAC).
Agilità
  • Richiede impegno per creare o eliminare le nuove tabelle, gli indici associati e i controlli di sicurezza creati tramite FGAC
  • L'offboarding di un cliente comporta l'eliminazione delle tabelle
    • Potrebbe avere un impatto negativo temporaneo sulle prestazioni di altri tenant all'interno del database
Operazioni
  • Nessuna operazione separata per i tenant
  • Il backup, il monitoraggio e il logging devono essere implementati come funzioni di applicazione separate o come script di utilità
Scala
  • Un singolo database può contenere solo 5000 tabelle
    • Solo 5000/<numero di tabelle per tenant> tenant in ogni database
    • Quando il database supera le 5000 tabelle, aggiungi un nuovo database per gli altri tenant
Prestazioni
  • Isolamento delle risorse: risorse dell'infrastruttura sottostante condivisa. È possibile un elevato livello di contesa delle risorse.
    • I vicini rumorosi influiscono sulle prestazioni.
  • Risorse minime per tenant: poiché esiste un limite di 100 database per istanza e 5000 tabelle per database, la capacità di calcolo minima richiesta per 500.000 tenant è un nodo.
  • Uso efficiente delle risorse: i tenant condividono le risorse di un'istanza. Ogni tenant può utilizzare la risorsa inattiva di altri tenant.
  • Selezione della posizione per l'ottimizzazione della latenza: se non utilizzi la funzionalità di partizionamento geografico, la posizione del database è la stessa della configurazione dell'istanza. Non puoi personalizzare la posizione del database per ogni tenant. Tuttavia, se utilizzi la funzionalità di partizionamento geografico, puoi creare partizioni dell'istanza in posizioni diverse e puoi inserire i dati in posizioni diverse utilizzando una chiave di posizionamento delle righe. L'utilizzo del partizionamento geografico ottimizza la latenza per ogni tenant.
Requisiti normativi e di conformità
  • Se non utilizzi la funzionalità di partizionamento geografico, la posizione dei database è la stessa della configurazione dell'istanza per soddisfare i requisiti normativi di residenza dei dati. Tuttavia, se utilizzi la funzionalità di partizionamento geografico, puoi creare partizioni di istanze in località diverse e inserire i dati in località diverse utilizzando una chiave di posizionamento per riga.
  • Tabelle diverse nello stesso database devono utilizzare la stessa CMEK per la crittografia dei dati in ogni regione.

In sintesi, i concetti chiave sono:

  • Vantaggio:livello moderato di scalabilità ed efficienza delle risorse.
  • Svantaggio:
    • Livello moderato di isolamento dei dati e delle risorse.
    • Mancanza di flessibilità della località se non si utilizza la nuova funzionalità di partizionamento geografico.
    • Impossibilità di monitorare separatamente i tenant. Le uniche informazioni sul consumo di risorse a livello di tabella disponibili sono le statistiche sulle dimensioni della tabella.
    • I tenant non possono avere CMEK e backup propri.

Il pattern di gestione dei dati delle tabelle è più adatto ai seguenti scenari:

  • Applicazioni multi-tenant che non richiedono legalmente la separazione dei dati, ma vuoi la separazione logica e il controllo della sicurezza.
  • Il costo è un fattore importante da considerare. Il costo minimo per tenant è inferiore al costo per database.

Riga

Il pattern finale di gestione dei dati serve più tenant con un insieme comune di tabelle, con ogni riga appartenente a un tenant specifico. Questo pattern di gestione dei dati rappresenta un livello estremo di multi-tenancy in cui tutto, dall'infrastruttura allo schema almodello dei datii, è 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 dello scaling, Spanner supporta al meglio questo pattern perché può scalare le tabelle senza limitazioni.

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

Come mostrato nel seguente diagramma, il pattern di gestione dei dati delle righe ha una tabella per più tenant.

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

A differenza di tutti gli altri pattern, l'accesso ai dati nel pattern di riga non può essere controllato separatamente per tenant diversi. L'utilizzo di un numero inferiore di tabelle significa che 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 l'onboarding, l'offboarding e le operazioni.

La tabella seguente illustra in che modo il pattern di gestione dei dati delle righe influisce sui diversi criteri.

Criteri Riga: un insieme di righe per ogni pattern di gestione dei dati dei tenant
Isolamento dei dati
  • Livello più basso di isolamento dei dati
  • Nessuna sicurezza a livello di tenant
Agilità
  • Nessuna configurazione richiesta sul lato database durante l'onboarding
    • L'applicazione può scrivere direttamente i dati nelle tabelle esistenti
  • L'offboarding comporta l'eliminazione delle righe del cliente nella tabella
Operazioni
  • Nessuna operazione separata per i tenant, inclusi backup, monitoraggio e logging
  • Overhead minimo o nullo all'aumentare del numero di tenant
Scala
  • Può ospitare qualsiasi livello di crescita dei tenant
  • Supporta un numero illimitato di tenant
Prestazioni
  • Isolamento delle risorse:
    • Tutti i problemi di isolamento delle risorse che si verificano nel pattern del database si applicano anche a questo pattern.
    • Se gli spazi delle chiave primaria non sono progettati con attenzione, è possibile un elevato livello di contesa delle risorse (vicino rumoroso).
      • Può impedire la concorrenza e la distribuzione
      • Seguire le best practice è importante
      • L'eliminazione dei dati di un tenant potrebbe avere un impatto temporaneo sul carico
  • Risorse minime per tenant: nessuna risorsa minima per tenant
  • Uso efficiente delle risorse: i tenant condividono le risorse di un'istanza. Ogni tenant può utilizzare le risorse inattive di altri tenant.
  • Selezione della posizione per l'ottimizzazione della latenza: se non utilizzi la funzionalità di partizionamento geografico, la posizione del database è la stessa della configurazione dell'istanza. Non puoi personalizzare la posizione del database per ogni tenant. Tuttavia, se utilizzi la funzionalità di partizionamento geografico, puoi creare partizioni dell'istanza in posizioni diverse e puoi inserire i dati in posizioni diverse utilizzando una chiave di posizionamento delle righe. L'utilizzo del partizionamento geografico ottimizza la latenza per ogni tenant.
Requisiti normativi e di conformità
  • Se non utilizzi la funzionalità di partizionamento geografico, la posizione dei database è la stessa della configurazione dell'istanza per soddisfare i requisiti normativi di residenza dei dati. Tuttavia, se utilizzi la funzionalità di partizionamento geografico, puoi creare partizioni di istanze in località diverse e inserire i dati in località diverse utilizzando una chiave di posizionamento per riga.
  • Il pattern non può fornire il partizionamento a livello di sistema (rispetto al pattern di istanza o database).
  • L'implementazione di controlli di sicurezza e audit specifici influisce su tutti i tenant.

In sintesi, i concetti chiave sono:

  • Vantaggio: altamente scalabile; ha un basso overhead operativo; gestione dello schema semplificata.
  • Svantaggio:elevata contesa delle risorse; mancanza di controlli di sicurezza e monitoraggio per ogni tenant.

Questo pattern è più adatto ai seguenti scenari:

  • Applicazioni interne destinate a diversi reparti in cui l'isolamento rigoroso della sicurezza dei dati non è una preoccupazione importante rispetto alla facilità di manutenzione.
  • Massima condivisione delle risorse per i tenant che utilizzano l'applicazione di livello gratuito riducendo al minimo il provisioning delle risorse contemporaneamente.

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

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

Istanza Database Tabella Riga
Isolamento dei dati Completa Alta Moderata Bassa
Agilità Bassa Moderata Moderata Più alto
Facilità di utilizzo Alta Alta Bassa Bassa
Scala Alta Limitato (a meno che non vengano utilizzate istanze aggiuntive al raggiungimento del limite) Limitato (a meno che non vengano utilizzati database aggiuntivi al raggiungimento del limite) Più alto
Rendimento1 - Isolamento delle risorse Alta Bassa Bassa Bassa
Rendimento1: risorse minime per tenant Alta Moderatamente alto Moderata Nessun minimo per tenant
Rendimento1 - Efficienza delle risorse Bassa Alto Alto Alta
Prestazioni1: selezione della posizione per l'ottimizzazione della latenza Alta Moderata Moderata Moderata
Regolamenti e conformità Più alto Alta Moderata Bassa

1 Le prestazioni dipendono molto dalla progettazione dello schema e dalle best practice per le query. I valori qui riportati sono solo una media prevista.

I migliori pattern di gestione dei dati per un'applicazione multi-tenant specifica sono quelli che soddisfano la maggior parte dei suoi requisiti in base ai criteri. Se un determinato criterio non è obbligatorio, 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ò presupporre un unico pattern di gestione dei dati.

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 economicamente vantaggioso
    • Deve avere un limite superiore per il volume di dati
    • Di solito supporta funzionalità limitate
    • Il pattern di gestione dei dati delle righe è un buon candidato per il livello gratuito
      • La gestione dei tenant è semplice
      • Non è necessario creare risorse tenant specifiche o esclusive
  • Livello Standard:

    • Ideale per i clienti paganti che non hanno requisiti di scalabilità o isolamento particolarmente stringenti.
    • Il pattern di gestione dei dati delle tabelle o il pattern di gestione dei dati dei database è un buon candidato per il livello standard:
      • 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 delle tabelle.
        • Il backup del tenant deve essere implementato come utilità esterna a Spanner.
  • Livello Enterprise:

    • In genere un livello di lusso con piena autonomia in tutti gli aspetti.
    • Il tenant dispone di risorse dedicate che includono scalabilità dedicata e isolamento completo.
    • Il pattern di gestione dei dati delle istanze è adatto al 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, in questo modo è difficile implementare la logica di accesso e le operazioni del ciclo di vita dell'applicazione.

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

Gestire il ciclo di vita del tenant

I tenant hanno un ciclo di vita. Pertanto, devi implementare le operazioni di gestione corrispondenti all'interno della tua 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:

  • Esportare i dati del tenant:

    • Quando elimini un tenant, è consigliabile esportare prima i suoi dati e, se possibile, rendergli disponibile il set di dati.
    • Quando utilizzi il pattern di gestione dei dati di righe o tabelle, il sistema di applicazioni multi-tenant deve implementare l'esportazione o mapparla alla funzionalità di database (esportazione del database) e implementare una logica personalizzata per estrarre la parte dei dati corrispondente al tenant.
  • Eseguire 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, utilizza le funzioni di esportazione o backup del database.
    • Quando utilizzi il pattern di gestione dei dati di tabelle o righe ed esegui il backup dei dati per singoli tenant, l'applicazione multitenant deve implementare questa operazione. Il database Spanner non è in grado di determinare a quale tenant appartengono i dati.
  • 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 dei dati tra istanze o database) richiede l'estrazione dei dati da un pattern di gestione dei dati e l'inserimento di questi dati nel nuovo pattern di gestione dei dati.

    • Un altro motivo per trasferire gli inquilini è la mitigazione di una situazione di vicinato rumoroso.

Progettazione di applicazioni

Quando progetti un'applicazione multi-tenant, implementa una logica di business che riconosca i 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 del database, la progettazione dell'applicazione implica che ogni query deve essere eseguita in base al pattern di gestione dei dati in cui risiede il tenant. Le sezioni seguenti mettono in evidenza alcuni dei concetti centrali della progettazione di applicazioni multi-tenant.

Configurazione dinamica della connessione e delle query del tenant

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

  • Per i pattern di gestione dei dati del database o i pattern di gestione dei dati delle istanze, una stringa di connessione è sufficiente per accedere ai dati di un tenant.
  • Per i pattern di gestione dei dati delle tabelle, è necessario determinare i nomi delle tabelle corretti.
  • Per i pattern di gestione dei dati delle righe, utilizza i predicati appropriati per recuperare i dati di un tenant specifico.

Un tenant può risiedere in uno qualsiasi dei quattro modelli di gestione dei dati. La seguente implementazione del mapping riguarda una configurazione di connessione per il caso generale di un'applicazione multi-tenant che utilizza contemporaneamente tutti i pattern di gestione dei dati. Quando un determinato tenant risiede in un pattern, alcune applicazioni multi-tenant utilizzano un pattern di gestione dei dati per tutti i tenant. Questa richiesta è coperta implicitamente dal seguente mapping.

Se un tenant esegue una 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 della tabella).

Questa logica dell'applicazione richiede il mapping del pattern tenant-to-data-management. Nel seguente esempio di codice, connection string si riferisce al database in cui risiedono i dati del tenant. L'esempio identifica l'istanza e il database Spanner. Per l'istanza del pattern di gestione dei dati e il database, il seguente codice è sufficiente per consentire all'applicazione di connettersi ed eseguire query:

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

È necessario un design aggiuntivo per i pattern di gestione dei dati di tabelle e righe.

Pattern di gestione dei dati delle tabelle

Per il pattern di gestione dei dati delle tabelle, esistono diversi tenant all'interno dello stesso database. Ogni tenant ha il proprio set di tabelle. Le tabelle si distinguono per il nome. A quale tenant appartiene una tabella è deterministico.

Un approccio consiste nel posizionare la tabella di ogni tenant in uno spazio dei nomi denominato come il tenant e qualificare completamente il nome della tabella con namespace.name. Ad esempio, inserisci una tabella EMPLOYEE all'interno dello spazio dei nomi T356 per il tenant con l'ID 356 e la tua applicazione può utilizzare T356.EMPLOYEE per indirizzare le richieste alla tabella.

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

Se vuoi utilizzare un altro testo al posto dell'ID tenant, puoi mantenere una mappatura dall'ID tenant allo spazio dei nomi dello schema denominato o al prefisso della tabella.

Per semplificare la logica dell'applicazione, puoi introdurre un livello di indirezione. Ad esempio, puoi utilizzare una libreria comune con la tua applicazione per allegare automaticamente il prefisso dello spazio dei nomi o della tabella per la chiamata dal tenant.

Pattern di gestione dei dati delle righe

Per il pattern di gestione dei dati delle righe è necessario un design simile. In questo pattern, c'è un solo schema. I dati del 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 l'inquilino appropriato è avere una colonna chiamata TENANT in ogni tabella. Per un migliore isolamento dei dati, il valore di questa colonna deve far parte della chiave primaria. Il valore della colonna è tenant ID. Ogni query deve aggiungere un predicato AND TENANT = tenant ID a una clausola WHERE esistente o aggiungere una clausola WHERE con il predicato AND TENANT = tenant ID.

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

Alcune operazioni del ciclo di vita richiedono la modifica della configurazione del mapping tenant-pattern di gestione dei dati, 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 di query e attribuzione

Un principio fondamentale delle applicazioni multi-tenant è che più tenant possono condividere una singola risorsa cloud. I pattern di gestione dei dati precedenti rientrano in questa categoria, ad eccezione del 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 delle tabelle e nel pattern di gestione dei dati delle righe, 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. Nel pattern di gestione dei dati delle righe, devi analizzare il predicato. Nel pattern di gestione dei dati della tabella, 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 le informazioni sul tenant per questi pattern, devi eseguire una query sulla tabella di mappatura tenant-pattern di gestione dei dati.

Sarebbe più facile analizzare log e 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) label.

La seguente query seleziona tutti i dati dei dipendenti per il tenant identificato da TENANT 356. Per evitare di analizzare la sintassi SQL ed 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}

Puoi anche utilizzare i tag per attribuire le query ai tenant e visualizzare le statistiche nelle tabelle spanner_sys integrate.

Operazioni del ciclo di vita dell'accesso al 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 può creare uno strumento di amministrazione dei tenant separato.

Indipendentemente dalla strategia di implementazione, le operazioni del ciclo di vita potrebbero dover essere eseguite senza che la logica dell'applicazione venga eseguita 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 a tutta la logica dell'applicazione consentendo 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 interferirebbero con la logica dell'applicazione sono disattivate.

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

Deve essere disponibile anche un'operazione del ciclo di vita corrispondente che rimuova 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 livelli di isolamento dei dati dei tenant. Dal livello più isolato (istanza) a quello meno isolato (riga), sono possibili diversi gradi di isolamento.

Nel contesto di un'applicazione multi-tenant, deve essere presa una decisione di deployment simile: tutti i tenant accedono ai propri dati (con pattern di gestione dei dati possibilmente 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 a un deployment dell'applicazione esclusivo, mentre i tenant più piccoli o i tenant nel livello gratuito condividono un deployment dell'applicazione.

Anziché abbinare direttamente i pattern di gestione dei dati descritti in questo documento 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 una singola implementazione dell'applicazione. È possibile avere il pattern di gestione dei dati del database e tutti questi tenant condividono un singolo deployment dell'applicazione.

Il multi-tenancy è un importante pattern di gestione dei dati di progettazione delle applicazioni, soprattutto quando l'efficienza delle risorse svolge un ruolo fondamentale. Spanner supporta diversi pattern di gestione dei dati. Utilizzalo per implementare applicazioni multi-tenant. Fornisce zero tempi di inattività per la manutenzione pianificata o gli errori di regione, con uno SLA (accordo sul livello del servizio) di disponibilità del 99,999%. Supporta anche applicazioni moderne e multi-tenant fornendo alta disponibilità e scalabilità.