Notes on Virtuoso population - dkmfbk/knowledgestore GitHub Wiki
Ho fatto alcuni test di popolamento di Virtuoso su dkm-server-1, con l'obiettivo di ottimizzare le performance (in ottica valutazione tempi popolamento KS).
Questi i metodi di popolamento testati:
- ttlp() con singolo file tql.gz
- ttlp_mt() con singolo file tql.gz (_mt = versione multi-thread)
- rdf_loader_run() con 20 file .nt.gz e 20 thread paralleli (metodo di 'bulk loading' suggerito da OpenLink)
In tutti e tre i casi ho usato il flag 767 = 512 (TQL/NQ) + 255 (abilitati tutti e 8 i flag che rendono più permissivo il caricamento). Il flag 767 è cablato nel metodo rdf_loader_run() e non si può cambiare.
Di seguito i risultati ottenuti:
Metodo Tempo # Triple
--------------------------------------------------------
ttlp() flag 767, 1 file .tql.gz 14'39" 95912799
ttlp() flag 767, 20 file .nq.gz seq 18'08" 95911211
rdf_loader_run() .nt.gz 20 thread 7'43" 95911211
Note:
- il tempo di caricamento bulk con rdf_loader_run è 5'28" una volta rigenerati i file singoli in formato .nq.tql.gz e senza farli esplodere in dimensione (e.g., @write -c 100000).
- in tutti e tre i casi, prima di fare il popolamento ho eliminato le triple pre-caricate in Virtuoso ('di sistema', diciamo)
- il numero esatto di triple determinato con RDFpro è 95910378: Virtuoso riporta 833 triple in più usando i 20 file .nt.gz, 2421 triple in più usando il singolo file .tql.gz. La differenza tra i due tipi di popolamento è 1588 triple e tale valore l'ho misurato in due caricamenti volte in modo consistente (la prima volta con flag ttlp diverso, quindi non è questo). Le triple diverse sono nel grafo dbpedia-en, ma più di cosi non so dire non riuscendo a fare export da Virtuoso in modo efficiente
- subito dopo il caricamento, il numero di triple riportato è approssimato per difetto e occorre riavviare Virtuoso per ottenere il numero di triple esatto
- rdf_loader_run() provato due volte con stessi risultati consistenti
- ho predisposto uno script (su cui sto ancora lavorando) che permette di automatizzare l'invocazione di rdf_loader_run() (piuttosto complessa) con un singolo comando
- rdf_loader_run() si può usare anche con file tql, basta che il loro nome contenga la sottostringa '.nq' da qualche parte (la cosa più pulita compatibile sia con rdfpro che con rdf_loader_run() è generare i file come .nq.tql.gz)
- la differenza di 1588 triple tra i diversi tipi di popolamento resta inspiegata. A parità di formato, questa non dipende da file singolo vs file multipli, per cui tutti i metodi di caricamento danno stessi risultati (testato con formato nq). In teoria, Virtuoso gestisce internamente .tql e .nq nello stesso modo, quindi la differenza non dovrebbe dipendere nemmeno dal formato. Quindi?
- ho dimenticato di specificare prima che la versione ttlp_mt() da le stesse performance della ttlp() base, quindi inutile considerarla ulteriormente.
- quando si spezzano i dati su più file con RDFpro, usare @write -c N con N = dimensione chunk allocato a singolo file, scelto più grande possibile per preservare ordine triple, altrimenti i file prodotti sono fino a 1.5 volte più grandi (complessivamente) del file di partenza (causa compressione peggiore)
- triple e grafi di sistema in un Virtuoso 'vergine' sono le seguenti:
http://www.openlinksw.com/schemas/virtrdf# 2647
http://localhost:8890/DAV/ 2991
http://www.w3.org/2002/07/owl# 160
http://localhost:8890/sparql 14
http://www.w3.org/ns/ldp# 3
----
5815
Popolamento multi-thread
Durante l'import bulk (BK + annotazioni) ho avuto per 2 volte l'errore:
23000 SR197: Non unique primary key on DB.DBA.RDF_LANGUAGE.
L'errore ha colpito due batch diversi (= a caso) che di conseguenza sono stati caricati solo in parte (4M triple si sono perse). Sembra un problema di race condition tra i 20 thread respondabili del caricamento concorrente. Si vede che sincronizzazione e controllo di concorrenza in Virtuoso seguono un approccio del tipo 'che Dio ce la mandi buona' (aka roulette russa) ...
Lessons learnt:
-
un workaround efficace per il problema sopra sembra essere dare meno memoria a Virtuoso (passare da 32 GB a 16 GB ha risolto)
-
dopo il caricamento, è opportuno:
- riavviare virtuoso (altrimenti ritorna numeri di triple a caso)
- via isql-vt, fare: select * from load_list; per vedere lo stato dei vari batch caricati, e verificare non ci siano errori strani
- controllare bene il numero di triple nel DB rispetto a quello che ci si aspetterebbe (in genere Virtuoso carica qualcosa di più - chissà da dove prende le triple extra...)
-
ma forse, se si tiene ai propri dati, val la pena di usare la vecchia e 'collaudata' ttlp ...
Per chiudere, anche questa volta il throughput in caricamento cresce contro-intuitivamente al crescere del dataset... Non solo, anche il costo per quadrupla scende. È come se ci fosse un qualche overhead su db piccoli. Sarebbe da provare con qualche miliardata di triple (vedi dump RDF cars2) per vedere se questi trend proseguono anche con input più grandi oppure si invertono (quello sul throughput) o stabilizzano.