Prime impressioni di Amazon Neptune

Salute, residenti di Khabrovsk. In anticipazione di u principiu di u corsu "AWS per sviluppatori" Avemu preparatu una traduzzione di materiale interessante.

Prime impressioni di Amazon Neptune

In parechji casi di usu chì ci piace bakdataCumu vedemu nantu à i siti web di i nostri clienti, l'infurmazioni pertinenti sò oculate in cunnessione trà entità, per esempiu quandu analizà e relazioni trà l'utilizatori, dipendenze trà elementi, o cunnessione trà i sensori. Tali casi d'usu sò generalmente modellati nantu à un graficu. A principiu di questu annu, Amazon hà publicatu a so nova basa di dati grafica, Neptune. In questu post vulemu sparte e nostre prime idee, e boni pratiche è ciò chì pò esse migliuratu cù u tempu.

Perchè avemu bisognu di Amazon Neptune

E basa di dati di gràficu prumettenu di gestisce insemi di dati altamente cunnessi megliu cà i so equivalenti relazionali. In tali datasets, l'infurmazioni pertinenti sò generalmente almacenati in relazioni trà l'uggetti. Avemu usatu un maravigghiusu prughjettu di dati aperti per pruvà Neptune MusicBrainz. MusicBrainz raccoglie ogni tipu di metadati musicali imaginabile, cum'è infurmazione nantu à artisti, canzoni, album o cuncerti, è ancu quale l'artista daretu à a canzone hà collaboratu cù o quandu l'album hè statu liberatu in quale paese. MusicBrainz pò esse vistu cum'è una grande reta di entità chì sò in qualchì modu cunnessi à l'industria musicale.

U dataset MusicBrainz hè furnitu cum'è un dump CSV di una basa di dati relazionale. In totale, u dump cuntene circa 93 milioni di fila in 157 tavule. Mentre chì alcune di sti tavule cuntenenu dati basi cum'è artisti, avvenimenti, registrazioni, versioni o piste, altri ligami tabelle - magazzini relazioni trà artisti è gravazioni, altri artisti o liberazioni, etc... Dimustranu a struttura gràfica di un settore di dati. Quandu cunvertisce u dataset in triple RDF, avemu ottenutu circa 500 milioni di casi.

Basatu nantu à l'esperienza è l'impressioni di i partenarii di u prughjettu cù quale avemu travagliatu, avemu prisentatu un ambiente in quale sta basa di cunniscenza hè aduprata per ottene nova infurmazione. Inoltre, aspittemu chì sia aghjurnatu regularmente, per esempiu aghjunghjendu novi versioni o aghjurnà i membri di u gruppu.

cutter

Cum'è previstu, installà Amazon Neptune hè simplice. Hè abbastanza dettagliata documentatu. Pudete lancià una basa di dati di gràficu in pochi clicchi. Tuttavia, quandu si tratta di cunfigurazione più dettagliata, infurmazione necessaria difficiuli di truvà. Dunque, vulemu indicà un paràmetru di cunfigurazione.

Prime impressioni di Amazon Neptune
Screenshot di cunfigurazione per i gruppi di parametri

Amazon dice chì Neptune si cuncentra nantu à carichi di travagliu transazionale di bassa latenza, per quessa chì u timeout predeterminatu di a dumanda hè di 120 seconde. Avemu, però, pruvatu parechji casi d'usu analiticu in quale avemu righjuntu regularmente stu limitu. Stu timeout pò esse cambiatu creendu un novu gruppu di paràmetri per Neptune è setting neptune_query_timeout restrizzioni currispundenti.

Caricà Dati

Quì sottu discuteremu in dettagliu cumu caricamu i dati MusicBrainz in Neptune.

Relazioni in trè

Prima, avemu cunvertitu i dati MusicBrainz in triple RDF. Dunque, per ogni tavula, avemu definitu un mudellu chì definisce cumu ogni colonna hè rapprisintata in u triple. In questu esempiu, ogni fila da a tavola di l'esecutore hè mappata à dodici triple RDF.

<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/gid> "${gid}"^^<http://www.w3.org/2001/XMLSchema#string> .
 
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/name> "${name}"^^<http://www.w3.org/2001/XMLSchema#string> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/sort-name> "${sort_name}"^^<http://www.w3.org/2001/XMLSchema#string> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/begin-date> "${begin_date_year}-${begin_date_month}-${begin_date_day}"^^xsd:<http://www.w3.org/2001/XMLSchema#date> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/end-date> "${end_date_year}-${end_date_month}-${end_date_day}"^^xsd:<http://www.w3.org/2001/XMLSchema#date> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/type> <http://musicbrainz.foo/artist-type/${type}> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/area> <http://musicbrainz.foo/area/${area}> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/gender> <http://musicbrainz.foo/gender/${gender}> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/comment> "${comment}"^^<http://www.w3.org/2001/XMLSchema#string> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/edits-pending> "${edits_pending}"^^<http://www.w3.org/2001/XMLSchema#int> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/last-updated> "${last_updated}"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
 
<http://musicbrainz.foo/artist/${id}> <http://musicbrainz.foo/ended> "${ended}"^^<http://www.w3.org/2001/XMLSchema#boolean> .

carica in massa

U modu suggeritu per carricà grandi quantità di dati in Neptune hè attraversu u prucessu di carica in massa via S3. Dopu avè caricatu i vostri schedarii triple à S3, cuminciate a carica cù una dumanda POST. In u nostru casu, hà pigliatu circa 24 ore per 500 milioni di triplets. Avemu aspittatu chì sia più veloce.

curl -X POST -H 'Content-Type: application/json' http://your-neptune-cluster:8182/loader -d '{
 
 
 "source" : "s3://your-s3-bucket",
 
 "format" : "ntriples",
 
 "iamRoleArn" : "arn:aws:iam::your-iam-user:role/NeptuneLoadFromS3",
 
 "region" : "eu-west-1",
 
 "failOnError" : "FALSE"
 
}'

Per evitari stu prucessu longu ogni volta chì lanciamu Neptune, avemu decisu di restaurà l'istanza da una snapshot in quale sti triplets eranu digià caricati. A corsa da una snapshot hè significativamente più veloce, ma sempre dura circa una ora finu à chì Neptune hè dispunibule per e dumande.

Quandu hà inizialmente caricatu triplets in Neptune, avemu scontru diversi errori.

{
 
 
 "errorCode" : "PARSING_ERROR",
 
 "errorMessage" : "Content after '.' is not allowed",
 
 "fileName" : [...],
 
 "recordNum" : 25
 
}

Alcune di elli eranu errori di analisi, cum'è mostratu sopra. Finu a data, ùn avemu ancu capitu ciò chì hè andatu male à questu puntu. Un pocu più di dettagliu aiuterà sicuramente quì. Stu errore hè accadutu per circa 1% di i tripli inseriti. Ma quantu à pruvà Neptune, avemu accettatu u fattu chì avemu travagliatu solu cù 99% di l'infurmazioni da MusicBrainz.

Ancu s'è questu hè faciule per e persone familiarizati cù SPARQL, sia cunzignatu chì i tripli RDF deve esse annotati cù tipi di dati espliciti, chì dinò pò causà errori.

Scaricamentu in streaming

Cumu l'esitatu sopra, ùn vulemu micca aduprà Neptune cum'è un magazzinu di dati staticu, ma piuttostu cum'è una basa di cunniscenza flexible è evolutiva. Allora avemu bisognu di truvà modi per intruduce novi tripli quandu a basa di cunniscenza cambia, per esempiu quandu un novu album hè publicatu o quandu vulemu materializà a cunniscenza derivata.

Neptune supporta l'operatori di input per mezu di e dumande SPARQL, sia crude sia basate in mostra. Discuteremu i dui approcci sottu.

Unu di i nostri scopi era di inserisce dati in una manera streaming. Cunsiderate di liberà un album in un novu paese. Da a perspettiva di MusicBrainz, questu significa chì per una versione chì include album, singuli, EP, etc., una nova entrata hè aghjuntu à a tavula. paese di liberazione. In RDF, currispondemu sta infurmazione cù dui novi triple.

INSERT DATA { <http://musicbrainz.foo/release-country/737041> <http://musicbrainz.foo/release> <http://musicbrainz.foo/release/435759> };INSERT DATA { <http://musicbrainz.foo/release-country/737041> <http://musicbrainz.foo/date-year> "2018"^^<http://www.w3.org/2001/XMLSchema#int> };

Un altru scopu era di ottene una nova cunniscenza da u graficu. Diciamu chì vulemu ottene u numeru di versioni chì ogni artista hà publicatu in a so carriera. Una tale dumanda hè abbastanza cumplessa è dura più di 20 minuti in Neptune, cusì avemu bisognu di materializà u risultatu per riutilizà sta nova cunniscenza in qualchì altra dumanda. Allora aghjunghjenu triple cù questa informazione torna à u gràficu, inserendu u risultatu di a subquery.

INSERT {
 
 
  ?artist_credit <http://musicbrainz.foo/number-of-releases> ?number_of_releases
 
} WHERE {
 
  SELECT ?artist_credit (COUNT(*) as ?number_of_releases)
 
  WHERE {
 
     ?artist_credit <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist-credit> .
 
     ?release_group <http://musicbrainz.foo/artist-credit> ?artist_credit .
 
     ?release_group <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/release-group> .
 
     ?release_group <http://musicbrainz.foo/name> ?release_group_name .
 
  }
 
  GROUP BY ?artist_credit
 
}

Adding single triples to the graph take some milliseconds, mentri u tempu d'esekzione per inserisce u risultatu di una subquery dipende da u tempu di esecuzione di a subquery stessu.

Ancu s'ellu ùn l'avemu micca usatu spessu, Neptune permette ancu di caccià i triplets basati nantu à campioni o dati espliciti, chì ponu esse usatu per aghjurnà l'infurmazioni.

dumande SPARQL

Intruducendu u subsample precedente, chì torna u numeru di versioni per ogni artista, avemu digià introduttu u primu tipu di quistione chì vulemu risponde cù Neptune. Custruì una dumanda in Neptune hè faciule - mandate una dumanda POST à ​​l'endpoint SPARQL, cum'è mostra quì sottu:

curl -X POST --data-binary 'query=SELECT ?artist ?p ?o where {?artist <http://musicbrainz.foo/name> "Elton John" . ?artist ?p ?o . }' http://your-neptune-cluster:8182/sparql

Inoltre, avemu implementatu una dumanda chì torna un prufilu d'artista chì cuntene infurmazioni nantu à u so nome, età o paese d'origine. Tenite in mente chì l'interpreti ponu esse individui, bandi o orchestre. In più, aghjustemu sta dati cù infurmazioni nantu à u numeru di emissioni liberate da l'artisti durante l'annu. Per l'artisti solisti, aghjustemu ancu infurmazioni nantu à e bandi chì l'artista participanu ogni annu.

SELECT
 
 
 ?artist_name ?year
 
 ?releases_in_year ?releases_up_year
 
 ?artist_type_name ?releases
 
 ?artist_gender ?artist_country_name
 
 ?artist_begin_date ?bands
 
 ?bands_in_year
 
WHERE {
 
 # Bands for each artist
 
 {
 
   SELECT
 
     ?year
 
     ?first_artist
 
     (group_concat(DISTINCT ?second_artist_name;separator=",") as ?bands)
 
     (COUNT(DISTINCT ?second_artist_name) AS ?bands_in_year)     
 
   WHERE {
 
     VALUES ?year {
 
       1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
 
       1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
 
       1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
 
       1990 1991 1992 1993 1994 1995 1996 1997 1998 1999
 
       2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
 
       2010 2011 2012 2013 2014 2015 2016 2017 2018
 
     }   
 
     ?first_artist <http://musicbrainz.foo/name> "Elton John" .
 
     ?first_artist <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist> .
 
     ?first_artist <http://musicbrainz.foo/type> ?first_artist_type .
 
     ?first_artist <http://musicbrainz.foo/name> ?first_artist_name .
 

 
 
     ?second_artist <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist> .
 
     ?second_artist <http://musicbrainz.foo/type> ?second_artist_type .
 
     ?second_artist <http://musicbrainz.foo/name> ?second_artist_name .
 
     optional { ?second_artist <http://musicbrainz.foo/begin-date-year> ?second_artist_begin_date_year . }
 
     optional { ?second_artist <http://musicbrainz.foo/end-date-year> ?second_artist_end_date_year . }
 

 
 
     ?l_artist_artist <http://musicbrainz.foo/entity0> ?first_artist .
 
     ?l_artist_artist <http://musicbrainz.foo/entity1> ?second_artist .
 
     ?l_artist_artist <http://musicbrainz.foo/link> ?link .
 

 
 
     optional { ?link <http://musicbrainz.foo/begin-date-year> ?link_begin_date_year . }
 
     optional { ?link <http://musicbrainz.foo/end-date-year> ?link_end_date_year . }
 

 
 
     FILTER (!bound(?link_begin_date_year) || ?link_begin_date_year <= ?year)
 
     FILTER (!bound(?link_end_date_year) || ?link_end_date_year >= ?year)
 
     FILTER (!bound(?second_artist_begin_date_year) || ?second_artist_begin_date_year <= ?year)
 
     FILTER (!bound(?second_artist_end_date_year) || ?second_artist_end_date_year >= ?year)
 
     FILTER (?first_artist_type NOT IN (<http://musicbrainz.foo/artist-type/2>, <http://musicbrainz.foo/artist-type/5>, <http://musicbrainz.foo/artist-type/6>))
 
     FILTER (?second_artist_type IN (<http://musicbrainz.foo/artist-type/2>, <http://musicbrainz.foo/artist-type/5>, <http://musicbrainz.foo/artist-type/6>))
 
   }
 
   GROUP BY ?first_artist ?year
 
 }
 
 # Releases up to a year
 
 {
 
   SELECT
 
     ?artist
 
     ?year
 
     (group_concat(DISTINCT ?release_name;separator=",") as ?releases)
 
     (COUNT(*) as ?releases_up_year)
 
   WHERE {
 
     VALUES ?year {
 
       1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
 
       1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
 
       1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
 
       1990 1991 1992 1993 1994 1995 1996 1997 1998 1999
 
       2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
 
       2010 2011 2012 2013 2014 2015 2016 2017 2018 
 
     }
 

 
 
     ?artist <http://musicbrainz.foo/name> "Elton John" .
 

 
 
     ?artist_credit_name <http://musicbrainz.foo/artist-credit> ?artist_credit .
 
     ?artist_credit_name <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist-credit-name> .
 
     ?artist_credit_name <http://musicbrainz.foo/artist> ?artist .
 
     ?artist_credit <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist-credit> .
 

 
 
     ?release_group <http://musicbrainz.foo/artist-credit> ?artist_credit .
 
     ?release_group <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/release-group> .
 
     ?release_group <http://musicbrainz.foo/name> ?release_group_name .
 
     ?release <http://musicbrainz.foo/release-group> ?release_group .
 
     ?release <http://musicbrainz.foo/name> ?release_name .
 
     ?release_country <http://musicbrainz.foo/release> ?release .
 
     ?release_country <http://musicbrainz.foo/date-year> ?release_country_year .
 

 
 
     FILTER (?release_country_year <= ?year)
 
   }
 
   GROUP BY ?artist ?year
 
 }
 
 # Releases in a year
 
 {
 
   SELECT ?artist ?year (COUNT(*) as ?releases_in_year)
 
   WHERE {
 
     VALUES ?year {
 
       1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
 
       1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
 
       1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
 
       1990 1991 1992 1993 1994 1995 1996 1997 1998 1999
 
       2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
 
       2010 2011 2012 2013 2014 2015 2016 2017 2018 
 
     }
 

 
 
     ?artist <http://musicbrainz.foo/name> "Elton John" .
 

 
 
     ?artist_credit_name <http://musicbrainz.foo/artist-credit> ?artist_credit .
 
     ?artist_credit_name <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist-credit-name> .
 
     ?artist_credit_name <http://musicbrainz.foo/artist> ?artist .
 
     ?artist_credit <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/artist-credit> .
 

 
 
     ?release_group <http://musicbrainz.foo/artist-credit> ?artist_credit .
 
     ?release_group <http://musicbrainz.foo/rdftype> <http://musicbrainz.foo/release-group> .
 
     ?release_group <http://musicbrainz.foo/name> ?release_group_name .
 
     ?release <http://musicbrainz.foo/release-group> ?release_group .
 
     ?release_country <http://musicbrainz.foo/release> ?release .
 
     ?release_country <http://musicbrainz.foo/date-year> ?release_country_year .
 

 
 
     FILTER (?release_country_year = ?year)
 
   }
 
   GROUP BY ?artist ?year
 
 }
 
 # Master data
 
 {
 
   SELECT DISTINCT ?artist ?artist_name ?artist_gender ?artist_begin_date ?artist_country_name
 
   WHERE {
 
     ?artist <http://musicbrainz.foo/name> ?artist_name .
 
     ?artist <http://musicbrainz.foo/name> "Elton John" .
 
     ?artist <http://musicbrainz.foo/gender> ?artist_gender_id .
 
     ?artist_gender_id <http://musicbrainz.foo/name> ?artist_gender .
 
     ?artist <http://musicbrainz.foo/area> ?birth_area .
 
     ?artist <http://musicbrainz.foo/begin-date-year> ?artist_begin_date.
 
     ?birth_area <http://musicbrainz.foo/name> ?artist_country_name .
 

 
 
     FILTER(datatype(?artist_begin_date) = xsd:int)
 
   }

A causa di a cumplessità di una tale dumanda, pudemu solu fà dumande di puntu per un artista specificu, cum'è Elton John, ma micca per tutti l'artisti. Neptune ùn pare micca ottimisà una tale dumanda abbandunendu i filtri in sottoselezzioni. Dunque, ogni selezzione deve esse filtrata manualmente per nome di l'artista.

Neptune hà carichi per ora è per I / O. Per a nostra prova, avemu usatu l'istanza minima di Neptune, chì costa $ 0,384 / ora. In u casu di a dumanda sopra, chì calcula u prufilu per un solu travagliadore, Amazon ci carica decine di millaie di operazioni I / O, chì implica un costu di $ 0.02.

cunchiusioni

Prima, Amazon Neptune mantene a maiò parte di e so prumesse. Cum'è un serviziu amministratu, hè una basa di dati di gràficu chì hè estremamente faciule d'installà è pò esse stallatu è funziona senza assai cunfigurazione. Eccu i nostri cinque risultati chjave:

  • A carica in massa hè faciule ma lenta. Ma pò esse cumplicatu cù missaghji d'errore chì ùn sò micca assai utili.
  • U scaricamentu in streaming sustene tuttu ciò chì ci aspettavamu è era abbastanza veloce
  • E dumande sò simplici, ma micca abbastanza interattive per eseguisce dumande analitiche
  • E dumande SPARQL devenu esse ottimizzate manualmente
  • I pagamenti di Amazon sò difficiuli di stimà perchè hè difficiule di stimà a quantità di dati scansati da una query SPARQL.

Eccu tuttu. Iscriviti per webinar gratuitu nantu à u tema "Load Balancing".


Source: www.habr.com

Add a comment