Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(quasi-)atomic import of data in arkimet #309

Open
dcesari opened this issue Jun 20, 2023 · 2 comments
Open

(quasi-)atomic import of data in arkimet #309

dcesari opened this issue Jun 20, 2023 · 2 comments
Assignees

Comments

@dcesari
Copy link
Member

dcesari commented Jun 20, 2023

Premetto che questa richiesta al momento non è stringente perché non abbiamo le corse modellistiche di backup al momento, la documento come possibile sviluppo futuro, per il momento la teniamo congelata.

In Arpae-SIMC vi sono alcuni flussi di importazione in archivi Arkimet di grossi dati previsionali che provengono da sorgenti ridondate e indipendenti (tipicamente due) per cui:

  1. è necessario importare, per uno specifico istante di emissione della sorgente, solo i dati provenienti dalla sorgente che termina per prima la produzione dei dati
  2. è importante evitare latenze e cominciare lo scanning dei dati il più presto possibile, mentre vengono generati
  3. i dati finali, per la corrente sessione di importazione, devono provenire tutti da una sola sorgente, non si possono mescolare, anche se in teoria sono equivalenti.

La funzionalità da implementare riguarda quindi la possibilità, mediante arki-scan o altro comando specifico, di pre-importare (-scannerizzare-indicizzare) i dati in Arkimet da tutte le sorgenti, ma fare il merge in modo atomico nel dataset finale di una sola della sorgenti, tipicamente quella che per prima ha completato, rendendoli disponibili ai client solo a merge effettuato. La cosa potrebbe essere implementata prevedendo la possibilità, anche per i dataset iseg grib/bufr, di avere un segmento distribuito anche su diversi file in sottocartelle, come per hdf, e fare sì che il merge finale consista solo in un mv di un file grosso sullo stesso filesystem e merge degli indici.

Sarebbe utile avere anche un comando di repack che permetta di impacchettare a bocce ferme tutti i file del segmento in un unico file per coerenza negli archivi storici.

@dcesari
Copy link
Member Author

dcesari commented Dec 12, 2023

La issue non è al momento urgente, per il momento chiediamo un giudizio di sensatezza/fattibilità e una stima dei tempi di realizzazione.

@spanezz
Copy link
Contributor

spanezz commented Dec 14, 2023

Mi sembra fattibile.

Come strategia di base:

  1. Aprire una transazione in sqlite per ogni import, oppure creare un file stile journal con le modifiche che sarebbero apportate al file sqlite del segmento

  2. Importare creando i segmenti in una directory temporanea. Si può fare un seek alla dimensione del segmento originale prima dell'import, per creare un buco all'inizio del segmento temporaneo in modo che gli offset dei dati importati siano in sincrono col segmento vero

  3. Quando si decide quale import va a buon fine:

    1. Si annullano gli altri import che stanno girando in parallelo, che faranno ROLLBACK in sqlite e cancelleranno i loro file temporanei
    2. Si copiano i dati dai segmenti temporanei a quelli online. L'operazione può essere ottimizzabile a livello di sistema operativo, per esempio usando copy_file_range
    3. Si esegue COMMIT su sqlite

Con alcune limitazioni:

  • Dei vari import in parallelo, solo zero o uno possono avere successo. Questo perché gli ID generati da sqlite durante gli import non sono allineati tra un import e l'altro, e quello che fa COMMIT invalida gli ID generati nelle altre transazioni; inoltre, non ci sarebbe modo di gestire i duplicati tra un import parallelo e un altro.
  • Un import di questo tipo conflitta con (e invalida) ogni altro tipo di import: rimarrebbe precauzione del chiamante serializzare gli import che non rientrano in questa competizione, finché la competizione non ha finito.

Considerazioni extra:

  • Implementata questa modalità di import, implementerei ogni import in modo che avvenga cosí. Avrebbe poi magari senso aggiungere un flag tipo --exclusive che si assicuri che non ci siano altri import in gara
  • Questo può aprire prospettive interessanti in termini di primitive di accesso ai dataset per eventuali sviluppi futuri, perché l'import diventa una procedura atomica che potenzialmente può fare il grosso del lavoro su un dataset read-only (specialmente se non si usano transazioni ma si mantiene un journal delle modifiche)

Tempo di lavorazione:

  • Direi una riunione per decidere i dettagli, e poi un mese di lavoro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants