Earste yndrukken fan Amazon Neptunus

Groetnis, Khabrovites. Foar it begjin fan 'e kursus "AWS foar ûntwikkelders" in oersetting makke fan nijsgjirrich materiaal.

Earste yndrukken fan Amazon Neptunus

Yn in protte fan 'e gebrûksgefallen dy't wy leuk fine bakdata, Wy sjogge op 'e websiden fan ús kliïnten, relevante ynformaasje is ferburgen yn relaasjes tusken entiteiten, bygelyks by it analysearjen fan relaasjes tusken brûkers, ôfhinklikens tusken eleminten of ferbiningen tusken sensoren. Sokke gebrûk gefallen wurde meastentiids modelearre op in grafyk. Earder dit jier hat Amazon in nije Neptunus-grafykdatabase frijlitten. Yn dit post wolle wy ús earste ideeën, goede praktiken diele, en wat kin wurde ferbettere yn 'e rin fan' e tiid.

Wêrom wy nedich Amazon Neptunus

Grafyske databases tasizze om tige ferbûne datasets better te behanneljen as har relasjonele tsjinhingers. Yn sokke datasets wurdt relevante ynformaasje meastal opslein yn relaasjes tusken objekten. Wy brûkten in geweldig iepen gegevensprojekt om Neptunus te testen MusicBrainz. MusicBrainz sammelet alle tinkbere metadata oer muzyk, lykas ynformaasje oer artysten, ferskes, albumútjeften of konserten, mei wa't de artyst dy't it liet makke hat gearwurke, of wannear't it album yn hokker lân útkaam. MusicBrainz kin sjoen wurde as in enoarm netwurk fan entiteiten dy't op ien of oare manier ferbûn binne mei de muzyksektor.

De MusicBrainz-dataset wurdt levere as in relaasje-database CSV-dump. Yn totaal befettet de dump sa'n 93 miljoen rigen yn 157 tabellen. Wylst guon fan dizze tabellen basisgegevens befetsje lykas artysten, eveneminten, opnames, releases of spoaren, oaren binne link tabellen - opslaan relaasjes tusken artysten en records, oare artysten of releases, etc ... Se demonstrearje de grafyk struktuer fan in gegevens set. By it konvertearjen fan de dataset nei RDF triples, krigen wy sawat 500 miljoen eksimplaren.

Op grûn fan de ûnderfining en yndrukken fan de projektpartners mei wa't wy wurkje, presintearje wy in ynstelling wêryn dizze kennisbasis brûkt wurdt om nije ynformaasje te krijen. Derneist ferwachtsje wy dat it regelmjittich bywurke wurdt, bygelyks troch nije releases ta te foegjen of groepsleden te aktualisearjen.

oanpassing

As ferwachte is it ynstallearjen fan Amazon Neptune maklik. Se is frij detaillearre. dokumintearre. Jo kinne in grafykdatabase starte mei mar in pear mûsklikken. As it lykwols giet om mear detaillearre konfiguraasje, nedige ynformaasje dreech te finen. Dêrom wolle wy wize op ien konfiguraasjeparameter.

Earste yndrukken fan Amazon Neptunus
Konfiguraasje skermprint foar parameter groepen

Amazon beweart dat Neptunus him rjochtet op transaksjonele workloads mei lege latency, en dat is de reden dat de standert fersyktiid 120 sekonden is. Wy hawwe lykwols in protte analytyske gebrûksgefallen hifke wêryn wy dizze limyt regelmjittich reitsje. Dizze timeout kin feroare wurde troch it meitsjen fan in nije parameter groep foar Neptunus en ynstelling neptune_query_timeout de oerienkommende beheining.

It laden fan gegevens

Hjirûnder sille wy yn detail beprate hoe't wy MusicBrainz-gegevens uploaden nei Neptunus.

Relaasjes yn trijen

Earst hawwe wy de MusicBrainz-gegevens konvertearre yn RDF-trijen. Dêrom, foar eltse tabel, wy hawwe definiearre in sjabloan dy't definiearret hoe't eltse kolom wurdt fertsjintwurdige yn in triple. Yn dit foarbyld wurdt elke rige yn 'e keunstnertabel yn kaart brocht oan tolve RDF-triples.

<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> .

bulk upload

De foarstelde manier om grutte hoemannichten gegevens te uploaden nei Neptunus is fia it bulk-uploadproses fia S3. Nei it uploaden fan jo triple triemmen nei S3, begjinne jo te uploaden mei in POST-fersyk. Yn ús gefal duorre it sawat 24 oeren foar 500 miljoen triples. Wy ferwachte dat it flugger soe wêze.

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"
 
}'

Om dit lange proses te foarkommen elke kear as wy Neptunus begjinne, hawwe wy besletten om in eksimplaar te herstellen fan in momintopname dy't dizze triples al hie laden. Begjin fan in momintopname is signifikant rapper, mar duorret noch sawat in oere oant Neptunus beskikber is foar oanfragen.

By it earstoan laden fan trijelingen yn Neptunus, rûnen wy ferskate bugs tsjin.

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

Guon fan harren wiene parseerfouten, lykas hjirboppe toand. Oant no ta hawwe wy noch net útfûn wat der op dit punt krekt misgien is. In bytsje mear detail soe perfoarst helpe hjir. Dizze flater barde foar sawat 1% fan 'e ynfoege trijelingen. Mar as it giet om it testen fan Neptunus, hawwe wy it feit akseptearre dat wy allinich wurkje mei 99% fan 'e ynformaasje fan MusicBrainz.

Sels as it maklik is foar minsken dy't bekend binne mei SPARQL, hâld der dan yn gedachten dat RDF-triples moatte wurde annotearre mei eksplisite gegevenstypen, wat wer flaters kinne feroarsaakje.

streaming download

Lykas hjirboppe neamd, wolle wy Neptunus net brûke as in statyske gegevenswinkel, mar as in fleksibele en evoluearjende kennisbasis. Dat wy moasten manieren fine om nije trijelingen yn te fieren as de kennisbasis feroaret, lykas as in nij album wurdt publisearre of as wy ôflaat kennis materialisearje wolle.

Neptunus stipet ynputútspraken fia SPARQL-fragen mei sawol rauwe gegevens as seleksjes. Wy sille beide oanpakken hjirûnder beprate.

Ien fan ús doelen wie gegevens yn te fieren yn streamingmodus. Besykje in album út te bringen yn in nij lân. Ut it eachpunt fan MusicBrainz betsjut dit dat foar in útjefte dy't albums, singles, EP's, ensfh., in nije yngong oan 'e tabel tafoege release-lân. Yn RDF bringe wy dizze ynformaasje yn kaart nei twa nije trijelingen.

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> };

In oar doel wie om nije kennis út de grafyk te heljen. Litte wy sizze dat wy it oantal releases wolle krije dy't elke artyst yn har karriêre hat publisearre. Sa'n query is frij kompleks en duorret mear as 20 minuten yn Neptunus, dus wy moatte it resultaat materialisearje om dizze nije kennis opnij te brûken yn in oare query. Dat wy foegje trijelingen mei dizze ynformaasje werom nei de grafyk troch it resultaat fan 'e subquery yn te spuiten.

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
 
}

It tafoegjen fan inkele triples oan de grafyk duorret in pear millisekonden, wylst de útfiering tiid foar it ynfoegjen fan it resultaat fan in subquery hinget ôf fan de útfiering tiid fan de subquery sels.

Wylst wy dit net folle hawwe brûkt, lit Neptunus jo ek trijelingen fuortsmite op basis fan seleksjes of eksplisite gegevens dy't kinne wurde brûkt om ynformaasje te aktualisearjen.

SPARQL-fragen

De foarige subsample yntrodusearje dy't it oantal releases foar elke artyst werombringt, wy hawwe it earste type query al ynfierd dat wy wolle beantwurdzje mei Neptunus. It bouwen fan in query yn Neptunus is maklik - stjoer in POST-fersyk nei it SPARQL-einpunt, lykas hjirûnder werjûn:

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

Derneist hawwe wy in query ymplementearre dy't in profyl fan artysten werombringt mei ynformaasje oer har namme, leeftyd of lân fan komôf. Hâld der rekken mei dat de artysten yndividuen, groepen of orkesten kinne wêze. Derneist komplementearje wy dizze gegevens mei ynformaasje oer it oantal releases dat troch artysten yn 't jier frijlitten is. Foar soloartysten foegje wy ek elk jier ynformaasje ta oer de groepen dêr't dizze artysten oan meidien hawwe.

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)
 
   }

Fanwegen de kompleksiteit fan sa'n query koene wy ​​allinnich puntfragen útfiere foar in spesifike artyst, lykas Elton John, mar net foar alle artysten. Neptunus liket sa'n query net te optimalisearjen troch filters yn subseleksjes te fallen. Dêrom moat elke stekproef manuell wurde filtere op artystenamme.

Neptunus hat sawol oere as per I / O-ladingen. Foar ús testen brûkten wy de meast minimale Neptune-eksimplaar, dy't $ 0,384 / oere kostet. Yn it gefal fan 'e query hjirboppe, dy't in profyl berekkent foar ien performer, kostet Amazon ús ferskate tsientûzenen IOPS, wat in kosten fan $ 0.02 ymplisearret.

konklúzje

Earst hâldt Amazon Neptune de measte fan har beloften. As in beheare tsjinst is, is it in grafyske databank dy't ekstreem maklik te ynstallearjen is en kin wurde begon sûnder folle konfiguraasje. Hjir binne ús fiif wichtige takeaways:

  • Bulk upload is ienfâldich, mar stadich. Mar it kin yngewikkeld wurde mei flaterberjochten dy't net heul nuttich binne.
  • Streaming stipet alles wat wy ferwachte en wie rap genôch
  • Queries binne ienfâldich, mar net ynteraktyf genôch om analytyske fragen út te fieren
  • SPARQL-fragen moatte manuell optimalisearre wurde
  • Amazon-betellingen binne dreech te skatten, om't it lestich is om de hoemannichte gegevens te skatten troch in SPARQL-query.

Da's alles. Opjaan foar fergees webinar oer load balancing.


Boarne: www.habr.com

Add a comment