Microservizi e archiviazione dei dati

20

Sto considerando di spostare un'API REST monolitica su un'architettura di microservice, e mi sto confondendo un po 'sull'archiviazione dei dati. A mio avviso, alcuni dei vantaggi dei microservizi sarebbero:

  • Scalabile orizzontalmente: posso eseguire più copie ridondanti di un microservizio per far fronte al carico e / o al server che va giù.
  • Abbastanza sciolto - Posso cambiare le implementazioni interne dei microservizi senza dover cambiare gli altri, e posso distribuirli e modificarli in modo indipendente, ecc ...

Il mio problema è con l'archiviazione dei dati. Per come la vedo ci sono diverse opzioni:

  1. Un singolo servizio di Database condiviso da tutti i microservizi - questo sembrerebbe eliminare completamente qualsiasi beneficio derivante dall'accoppiamento libero.
  2. Un'istanza di database installata localmente su ciascun microservizio: non riesco a vedere un modo per ridimensionarlo orizzontalmente, quindi non penso che sarebbe un'opzione.
  3. Ogni microservizio dispone del proprio servizio di database - questo sembra il più promettente, in quanto conserva i vantaggi dell'accoppiamento libero e del ridimensionamento orizzontale (utilizzando copie ridondanti del database e / o sharding su più)

Per me, la terza opzione sembra essere l'unica opzione, ma mi sembra incredibilmente pesante e una soluzione molto ipersensibile. Se sto capendo bene, quindi per una semplice applicazione con 4-5 microservizi dovrei eseguire 16-20 server - due istanze di microservizio effettive per microservizio (in caso di errore del server, e per la distribuzione senza tempi di fermo), e due istanze del servizio database per microservizio (in caso di errore del server ecc.).

Questo, francamente, sembra un po 'ridicolo. 16-20 server per eseguire una semplice API, tenendo presente che un progetto realistico avrà probabilmente più di 4-5 servizi? C'è qualche concetto fondamentale che mi manca che spiegherà questo?

Alcune cose che possono esserti d'aiuto durante la risposta:

  • Sono l'unico sviluppatore di questo progetto e lo sarà per il prossimo futuro.
  • Sto utilizzando Node.js e MongoDB, ma sarei interessato alle risposte indipendenti dalla lingua: una risposta potrebbe anche essere che sto usando le tecnologie sbagliate!
posta macleos 24.03.2018 - 23:30
fonte

3 risposte

17

Delle tre opzioni, la prima (un singolo database condiviso) e la terza (un "servizio database") sono le più comuni.

Il primo è chiamato database di integrazione . Questo in genere non è visto come una buona soluzione in un'architettura di microservizi. Aggiunge l'accoppiamento ai tuoi servizi. Rende anche molto semplice per un servizio semplicemente bypassare gli altri servizi e interrogare direttamente in un database. Potresti perdere qualsiasi tipo di integrità o convalida dei dati fornita dal livello dell'applicazione non applicato a livello di database.

La tua terza idea è chiamata database dell'applicazione . E hai ragione: ti consente di applicare l'accoppiamento libero a livello di API tra i servizi e ti consente di scalare più facilmente i servizi a livello di database. Inoltre, rende più semplice sostituire la tecnologia di database sottostante con qualcosa di appropriato con ciascun servizio, proprio come è possibile modificare la tecnologia o altri dettagli di implementazione di ciascun servizio. Molto flessibile.

Tuttavia, proporrei una soluzione intermedia.

Invece di alzare un servizio di database per ogni microservizio, alzare uno schema per ogni servizio. Se si utilizzano più tecnologie di database, potrebbe essere necessario dividere leggermente in modo diverso, ma l'idea sarebbe quella di ridurre al minimo il numero di server di database che si sta eseguendo, ma rendere molto semplice suddividere un servizio nel proprio server di database se e quando diventa necessario. Finché si consente solo a un database di accedere al proprio schema, si hanno i vantaggi di un database dell'applicazione ma senza il sovraccarico dei server database esistenti per ogni applicazione o servizio.

Tuttavia, come sviluppatore solista, sfiderei l'intera nozione di microservizi in questo momento storico - Martin Fowler scrive su Monolith Prima e Microservice Premium , Simon Brown parla di monoliti modulari , e DHH parla del Majestic Monolith . Non sono sicuro di come sia organizzato il tuo monolite, ma lo aggiusti e lo organizzi. Identifica i componenti e crea separazioni nette tra loro per estrarre facilmente i pezzi in un servizio. Lo stesso vale per la struttura del tuo database. Concentrarsi su un'architettura buona, pulita e basata su componenti in grado di supportare il refactoring nei servizi. I microservizi aggiungono un sacco di spese generali per un singolo sviluppatore da creare e supportare nelle operazioni. Tuttavia, una volta che hai effettivamente bisogno di ridimensionare parte del sistema, usa i tuoi sistemi di monitoraggio e reporting per identificare i colli di bottiglia, estrarre un servizio e ridimensionarlo se necessario.

    
risposta data 25.03.2018 - 00:29
fonte
1

Each microservice has it's own database service - this seems the most promising, as it preserves the benefits of loose coupling and horizontal scaling (using redundant database copies and/or sharding across several)

Sono d'accordo. L'opzione terzo è la scelta naturale per i micro servizi. Se il micro servizio deve essere realmente indipendente (e non parte di un monolito distribuito ), è normale che hanno, ciascuno, un database.

[...] two actual microservice instances per microservice (in case of server failure, and for deploying without downtime), and two database service instances per microservice (in case of server failure etc...).

Hai ragione riguardo alla quantità di micro servizi in esecuzione se desideri avere un bilanciamento del carico. Se stai pianificando di avere 4 micro servizi, devi preparare almeno 2 istanze di ciascun micro servizio (8 in totale), come già spiegato.

Ma due database per micro servizio? Questo è davvero discutibile. Non conosco i dettagli del problema aziendale a cui parteciperanno i tuoi micro servizi, ma ho una ridondanza del database che è abbastanza per la maggior parte dei prodotti / progetti. Raccomanderò di iniziare con un singolo database con un buon backup e minimizzare (almeno inizialmente) la complessità della tua infrastruttura.

This, quite frankly, seems slightly ridiculous. 16-20 servers to run a simple API, bearing in mind that a realistic project will probably have more than 4-5 services? Is there some fundamental concept that I'm missing that will explain this?

Per un'API semplice questi numeri non corrispondono. Fai attenzione se non stai cadendo in uno dei "Microservice First" trappole .

    
risposta data 25.03.2018 - 00:13
fonte
0

I microservizi sono una forma di architettura orientata ai servizi, forse all'estremo. Il loro scopo generale è quello di ridurre l'accoppiamento e consentire uno sviluppo indipendente e amp; distribuzione.

Molto approssimativamente in termini architettonici, microservices è un termine che si applica, diciamo, a livello logico. I microservizi sono logicamente separati l'uno dall'altro. Da questo punto di vista i microservizi dovrebbero ciascuno possedere e provvedere al proprio stoccaggio, che dovrebbe essere disaccoppiato dalla memorizzazione di altri microservizi. Per i microservizi, questa indipendenza di archiviazione è fondamentale per il loro obiettivo di modularità e accoppiamento lento.

Da una prospettiva architettonica, il ridimensionamento orizzontale si applica a un livello inferiore, più vicino all'implementazione, diciamo, a livello fisico. A questo livello, stiamo implementando un microservizio e possiamo decomporre questo singolo microservizio, internamente, in un componente stateless scalabile orizzontalmente e un componente stateful condiviso da tutti i componenti stateless. Ma non confondiamo solo la parte senza stato con il microservizio stesso.

Quindi, quando parliamo dei singoli microservizi, siamo al livello logico parlando di API e responsabilità separate e cicli di sviluppo / distribuzione separati. E quando parliamo di ridimensionamento orizzontale, siamo a livello fisico parlando dell'implementazione di un (singolo) microservizio e della sua scomposizione in componenti stateless e stateful.

Quando implementiamo più microservizi, abbiamo le opzioni per riutilizzare la tecnologia del database per i componenti stateful:

  • database separato per microservizio
  • database condiviso con:
    • schema separato / privato per microservizio
    • tabelle private / separate per microservizio

Vedi di più qui .

A single Database service shared by all microservices - this would seem to completely eliminate any benefit of loose coupling.

D'accordo, se intendi la condivisione di righe di tabelle e amp; colonne, che in realtà non sarebbero microservizi.

Se possiamo disaccoppiare - nei nostri processi mentali - la nozione logica dei microservizi dalla nozione più fisica di componenti stateful e stateless di un microservizio, potremmo trovare più facile ottenere l'accoppiamento libero offerto dai microservizi, pur mantenendo l'efficienza di un database condiviso.

Generalmente, c'è una buona dose di microservizi e persistenza dello stato, vedi anche qui .

    
risposta data 25.03.2018 - 17:13
fonte

Leggi altre domande sui tag