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.
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 |
|
Agilità |
|
Operazioni |
|
Scala |
|
Prestazioni |
|
Requisiti normativi e di conformità |
|
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 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 |
|
Agilità |
|
Operazioni |
|
Scala |
|
Prestazioni |
|
Requisiti normativi e di conformità |
|
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.
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 |
|
Agilità |
|
Operazioni |
|
Scala |
|
Prestazioni |
|
Requisiti normativi e di conformità |
|
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.
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 |
|
Agilità |
|
Operazioni |
|
Scala |
|
Prestazioni |
|
Requisiti normativi e di conformità |
|
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.
- Quando è possibile un downtime dell'applicazione, esegui un'esportazione/importazione.
- Quando il tempo di inattività non è possibile, esegui una migrazione del database senza tempi di inattività.
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à.