Archivia il file nel filesystem e i suoi metadati nel database atomicamente

1

Devo memorizzare molti file pdf / jpg / png di max 10mb in un filesystem, e devo salvare i loro metadati su un database.

SFTP e il DB possono trovarsi su diversi nodi. In WS, ho un db locale in cui posso controllare l'accesso e chiedere l'indirizzo al database e al filesystem.

Mi chiedevo: cosa succede se DB fallisce poco prima che io abbia caricato il file su SFTP? Oppure, ancora peggio, il WS fallisce prima di inserire dati nel DB. Dato che ho il vincolo di restituire l'id del nuovo inserto, non posso rimandare l'inserto, in che modo solitamente viene gestito questo tipo di sistema?

    
posta Federico Ponzi 12.09.2017 - 17:06
fonte

2 risposte

2

Ecco una risposta parziale, ma più pratica e probabilmente applicabile. I if processi successivi considerano solo i file tramite le loro voci di metadati, quindi il caricamento dei file e l'aggiornamento ai metadati non devono necessariamente essere atomici. Ciò significa che non è possibile avere un processo che elabora tutti i file nella directory SFTP. Dovrebbe invece recuperare l'elenco dei file dalla tabella dei metadati ed elaborare ciascun file nell'elenco risultante. Allo stesso modo, non è possibile avere un processo che controlli un file specifico nella directory; dovrebbe invece controllare una voce nella tabella dei metadati.

In questo contesto, puoi semplicemente caricare il file e, una volta verificato il caricamento, inserire un record di metadati. Se il processo fallisce in qualsiasi momento prima che l'inserimento dei metadati venga eseguito, si finisce con un file orfano innocuo. Ciò presuppone che i nomi dei file siano distinti; tuttavia, se passi sempre attraverso la tabella dei metadati, i nomi dei file nella directory SFTP non sono più importanti, quindi puoi semplicemente aggiungere un UUID alla fine di essi per garantire che siano distinti.

Potresti voler eliminare gli orfani (in particolare perché "sovrascrivere" un file in questo contesto significa semplicemente rendere orfano il vecchio file). Questo può essere fatto in un processo in background che cancella i file più vecchi di un certo orizzonte temporale, che può essere probabilmente di almeno 24 ore e probabilmente dell'ordine di mesi.

Se le ipotesi non si applicano, allora qualcosa come l'approccio di Christophe diventa necessario.

    
risposta data 13.09.2017 - 01:48
fonte
1

Hai 3 nodi (WS, SFTB e DB), ognuno dei quali esegue una parte dell'operazione. La difficoltà è che se uno qualsiasi dei nodi fallisce, gli altri devono eseguire il rollback del lavoro parziale.

Puoi ottenere ciò ad esempio con un protocollo di commit a 3 fasi : - il tuo WS potrebbe agire da coordinatore per le transazioni avviate - SFTP e DB funzionerebbero come partecipanti

Ogni nodo deve gestire la parte della transazione da impegnare o il rollback. Questo di solito richiede una registrazione dei lavori in corso, in modo che il nodo sia in grado di annullare le modifiche se deve eseguire il rollback (e anche dopo un arresto anomalo, al riavvio del sistema).

Attenzione: in questo schema, si presume che l'SFTP carichi solo nuovi file. Se avessi diversi WS e due di loro potessero caricare un file con lo stesso nome file, l'ultimo potrebbe sovrascrivere il lavoro del primo in modo che i metadati vengano corrotti (due record di metadati non corrispondenti per un file) e l'atomicità sia interrotta.

    
risposta data 12.09.2017 - 22:08
fonte

Leggi altre domande sui tag