La memorizzazione di file con dimensioni massime di 50 MB in un database per l'utilizzo da parte di più server è un'idea ragionevole? Esempio dentro

3

Sono in procinto di progettare un server responsabile della pubblicazione di file con dimensioni comprese tra 10 MB e 50 MB.
Inizialmente eseguiremo due istanze del server (chiamiamole fs1 e fs2 ), con i piani futuri di passare a un'architettura di micro-servizi, in cui le istanze del server aumenteranno o diminuiranno a seconda del carico.

Queste due istanze devono interagire con un terzo server che esegue un programma di pianificazione e un'applicazione di gestione file, nonché un database (su un altro server) in cui verranno salvati alcuni metadati da utilizzare per i client.

Le mie riflessioni iniziali su dove usare un rabbitmq per consentire a fs1 e fs2 di comunicare tra loro e l'app di gestione. il processo avrebbe funzionato come segue:

  1. L'app di gestione viene caricata sul server fs1 (potrebbe essere fs1 o fs2)
  2. fs1 notifica fs2 e l'app di gestione al termine del caricamento
  3. fs2 contatta fs1 e memorizza una copia del file
  4. fs2 notifica l'app di gestione al termine del caricamento
  5. L'app di gestione salva i metadati nel database esterno
  6. sia fs1 che fs2 ora possono eseguire il server dei file quando richiesto

Questo sembra OK, se ci sono solo due istanze, ma una volta che inizi ad aggiungerne altre non funziona.
Il nostro reparto operativo è molto contrario all'idea di utilizzare il database per archiviare i file. Sono preoccupati che rallenterà troppo il sistema. Sono d'accordo che potrebbe, ed è per questo che voglio un database separato per lo scopo specifico di archiviare i file e i metadati. Voglio costruire qualcosa di simile al seguente:

Penso che il servizio di upload possa gestire il caricamento di file e il salvataggio dei metadati nel database. Quando lo schedulatore pianifica un nuovo lavoro, il servizio di upload (mal chiamato, lo so, ma non lo faccio di nuovo :-)) può notificare le istanze del file server di cui hanno bisogno per memorizzare nella cache i file richiesti dal database, a cui possono accedere direttamente.
I file server non dovranno memorizzare più di 5 o 6 file alla volta.
Inoltre, nello schema mi sono perso il fatto che il servizio di gestione dei file riceverà i messaggi di avanzamento download da entrambi i file server.

Quindi alle mie domande:

  1. È un modo ragionevole per archiviare file di queste dimensioni per essere pubblicati?
  2. È questo il modo giusto di pensare quando si considera il passaggio ai microservizi in futuro?
  3. Ci sono dei vantaggi nell'archiviazione dei file sul file system di ogni istanza di fs invece che nella cache?
  4. Come posso convincere il nostro team operativo che la memorizzazione di 50 MB di file in un database è la strada da percorrere? quali sono i pro e i contro?
  5. Ogni altro pensiero o commento è apprezzato.
posta bot_bot 09.02.2018 - 09:57
fonte

4 risposte

7

NO, non memorizzare i file in un database relazionale

Fidati di me, ho imparato questo modo duro . Un problema con le applicazioni che si occupano di file, è come si evolvono, gli utenti vogliono sempre archiviare più di quanto l'applicazione era destinata a gestire.

Una volta ho creato un'applicazione con un componente di archiviazione dei documenti destinato a memorizzare documenti Word ed Excel. Il componente di archiviazione era abbastanza utile che alla fine le persone iniziarono a memorizzare video in esso.

Ne parlo perché, le implicazioni sulla performance saranno più alte di quanto ti aspetti; questo mi porta al mio prossimo punto.

Anche se un database può gestire file fini (tipo filestream) il ridimensionamento di un DB è difficile, è sempre la parte più difficile da scalare. Lascia che il db si concentri sul salvataggio e sul recupero dei dati, in questo modo puoi rimandare il ridimensionamento il più a lungo possibile. Se il DB è occupato a servire un file di grandi dimensioni, quelle sono risorse non utilizzate per servire le richieste di transazione e di ricerca; il suo pane e burro.

La sincronizzazione da server a server non si adatta bene

Il tuo sistema sembra troppo complicato per me, vorrei andare con un design più semplice. Il problema con i server fs1 e fs2 che parlano l'uno con l'altro è, man mano che si scala, il numero di percorsi aumenta esponenzialmente.

Con due server, ogni server deve solo fare una richiesta di sincronizzazione, per un totale di 2 percorsi. 3 severs, ci sono un totale di 6. Con 5 server ce ne sono 20. synchRequests = (n-1)*(n); n = number of servers

Avrei semplicemente un server DB dedicato e un server file dedicato a cui i server FSn parlano. Se hai bisogno di un comportamento di sincronizzazione più complesso, aggiungi un servizio Redis dedicato nel mix per fungere da unica fonte di verità per i dettagli non persistenti.

Il punto è, non avere fs1 che parla con fs2, o viceversa, questo non si ridimensiona.

Grafico

                             [ fs1 ] [ fs2 ] [ fs3 ] [ ect ]
                                |       |       |       |
                                +-------+---+---+-------+
                                            |
                         +------------------+-------------------+
                         |                  |                   |
                      [ RDB ]           [ Redis ]           [ Files ] 

Il meglio dei due mondi?

Puoi rimuovere molti degli svantaggi dall'archiviazione dei tuoi file in un RDB, e ottenere la maggior parte dei vantaggi separando un'istanza DB completamente separata e memorizzando solo i tuoi file lì. Questa è una valida opzione se non si desidera impostare e mantenere un file server.

Una breve parola sui microservizi

Non sono sicuro del motivo per cui vorrai seguire il percorso dei microservizi. L'intento originale dei microservizi è quello di aggirare i problemi politici , non i problemi tecnici. Ad esempio, l'amministratore del server si rifiuta di aprire qualsiasi porta diversa da 80.

    
risposta data 09.02.2018 - 19:24
fonte
2

Ovviamente, hai alcune opzioni ma ci sono anche dei compromessi. Per rispondere alle tue domande:

Is this a reasonable way to store files of this size for serving?

La risposta dipende molto dal tuo database e dai consigli per questo. Ad esempio, SQL Server ha un buon supporto per file di dimensioni arbitrarie se si utilizza l'opzione FILESTREAM (o qualcosa che a sua volta ne fa uso come FileTable). Ma otterrai una risposta diversa con qualcosa come Sqlite che può incorrere in problemi se il file del database complessivo diventa troppo grande.

Se stai ospitando nel cloud , la soluzione migliore è utilizzare l'archivio BLOB disponibile dal tuo provider. È anche possibile utilizzare qualcosa come la libreria JCloud (da Apache) per astrarre il vero fornitore cloud dal processo di archiviazione e recupero dei file dall'archivio BLOB. AWS lo chiama S3, ma tutti i provider hanno una sorta di archivio BLOB che è orientato a servire direttamente.

Is this the right way to be thinking when considering the move to microservices in the future?

Probabilmente no. Pensa ai microservizi come entità complete e autonome. Se utilizzi S3, un semplice archivio di file o un database dedicato.

Creando qualcosa come un microservizio "Blob Store", puoi usare gli hash per evitare file duplicati. Se due persone caricano lo stesso file con nomi o percorsi diversi, potresti essere ragionevolmente sicuro che ce ne sia solo una copia nell'archivio BLOB. Si memorizzerebbe il file con l'hash per il nome file e, se necessario, si potrebbero inserire i metadati in un file JSON che è archiviato con lo stesso nome file ma con estensione .json. O i tuoi metadati sono cercati da hash.

Are there advantages to storing the files on the file system of each fs instance instead of just caching?

Non tanto quanto usare S3 che nasconde l'intero problema di caching / storage, quindi non devi risolverlo.

Tuttavia, il file system consente di avere un maggiore controllo sul modo in cui i file vengono archiviati, consentendo la crittografia e / o la compressione a livello di servizio, se necessario.

How can I convince our ops team that storing 50MB files in a database is the way to go? what are the pros and cons?

Dipende da:

  1. Quanti file ci aspettiamo
  2. Quanto velocemente cresce
  3. Costo dell'indicizzazione

Maggiore è il numero di record con cui si ha a che fare, maggiore è il rischio di eventi di blocco anomalo che rallentano il sistema.

La caratteristica principale del killer di un database è che il backup e il ripristino includono sia il contenuto del file che i metadati. È ottimo per il disaster recovery, ma oltre a ciò i vantaggi iniziano a diminuire rapidamente.

L'utilizzo dello storage cloud riduce sostanzialmente la maggior parte dei problemi di disaster recovery con una storia di supporto migliore rispetto ai database tradizionali. Avrai comunque bisogno dell'archivio offsite per il ripristino di emergenza completo, ma questo è lo stesso requisito se hai un database.

Un semplice sistema di file è il più svantaggiato qui, ma puoi farcela con Hadoop File System (HFS) e ottenere un archivio di BLOB di nuvola all'interno della tua rete. Quindi ci sono alcune opzioni che non credo tu abbia ancora esplorato.

Any other thoughts or comments appreciated.

Sembra che tu stia passando più a una soluzione distribuita basata su cloud, ma continuando a pensare in termini di sviluppo tradizionali. Ho capito, sto ancora attraversando la curva di apprendimento con il lavoro in cui mi trovo ora. Abbiamo optato per un microservizio di Blob Store che utilizza lo storage cloud fornito. Ciò ci consente di evitare la memorizzazione di dati duplicati, ecc.

Sto anche supportando un'app legacy che ha dovuto cambiare la modalità di archiviazione dei file nel database in modo da poter gestire file più grandi. Cambiare il modo in cui i file sono archiviati in un database, attenendosi alle raccomandazioni del produttore del DB ha molte più implicazioni di quanto si possa pensare.

Penso che supererai il data base dei file più presto che dopo.

    
risposta data 09.02.2018 - 18:23
fonte
1

È possibile archiviare i file nei database, ma tutti i DBMS (relazionali) di cui sono a conoscenza sono generalmente progettati per memorizzare piccole parti di dati per voce. Ovviamente è possibile impostare un sistema DBMS aggiuntivo dal quale vengono serviti solo i file (alcune impostazioni delle prestazioni sono davvero raccomandate allora), ma alla fine i Filesystem sono già progettati per memorizzare i file, indipendentemente dalle loro dimensioni .

Quindi mi chiedo se hai pensato di usare un filesystem distribuito perché credo che sarebbe molto più semplice e performante. Ci sono molti di quei sistemi là fuori come

Ceph o

LizardFS

per nominarne solo alcuni.

Potresti quindi esporre il FileSystem distribuito all'AppServer dove può essere trattato come un volume locale fornendo al tempo stesso tutta la capacità di archiviazione necessaria (i file system distribuiti scalano molto bene).

Spero che questo aiuti

    
risposta data 09.02.2018 - 17:05
fonte
0

Certo, prova .

La maggior parte dei database supporta text e blob tipi esattamente per lo scopo di archiviare grandi blocchi di dati "non strutturati". Quindi, i più DBMS hanno già fatto considerazioni per il tuo caso d'uso. Ma lascia questo aspetto della tua applicazione aperto alla configurazione.

Idealmente, assicurati che le metriche siano in atto per monitorare tutto ciò che potrebbe cambiare in modo negativo - sia come risultato di questo sia in qualsiasi altro cambiamento nei modelli di utilizzo. Cose come la CPU utilizzo, disco IO, rete IO, latenza, ecc.

Se disponi di dati per mostrare l'impatto delle tue modifiche e la tua applicazione è aperta alla configurazione, puoi avere effettive conversazioni sull'impatto delle tue decisioni e puoi ruotare rapidamente quando realizzi un cattiva decisione.

Con i dati in mano, le opinioni di un gruppo di estranei su Internet non hanno alcun significato, e tu ei tuoi colleghi potete avere conversazioni razionali e produttive.

    
risposta data 09.02.2018 - 16:28
fonte

Leggi altre domande sui tag