Esimesed muljed Amazon Neptune'ist

Tervitused, Habrovski elanikud. Kursuse alguse ootuses "AWS arendajatele" Oleme koostanud huvitava materjali tõlke.

Esimesed muljed Amazon Neptune'ist

Paljudel kasutusjuhtudel, mis meile meeldivad bakdataNagu näeme oma klientide veebisaitidel, on asjakohane teave peidetud olemitevahelistes ühendustes, näiteks kasutajatevaheliste suhete, elementidevahelise sõltuvuse või anduritevaheliste ühenduste analüüsimisel. Selliseid kasutusjuhtumeid modelleeritakse tavaliselt graafiku alusel. Selle aasta alguses avaldas Amazon oma uue graafikute andmebaasi Neptune. Selles postituses tahame jagada oma esimesi ideid, häid tavasid ja seda, mida saaks aja jooksul paremaks muuta.

Miks me vajasime Amazon Neptune'i?

Graafikuandmebaasid lubavad käsitleda tihedalt ühendatud andmekogumeid paremini kui nende relatsioonilised ekvivalendid. Sellistes andmekogumites salvestatakse asjakohane teave tavaliselt objektidevahelistes suhetes. Kasutasime Neptuuni testimiseks hämmastavat avaandmete projekti MusicBrainz. MusicBrainz kogub igasuguseid mõeldavaid muusika metaandmeid, näiteks teavet artistide, lugude, albumiväljaannete või kontsertide kohta, samuti selle kohta, kellega loo taga olev esitaja koostööd tegi või millal album millises riigis välja anti. MusicBrainzi võib vaadelda kui tohutut üksuste võrgustikku, mis on mingil moel muusikatööstusega seotud.

MusicBrainzi andmekogumit pakutakse relatsiooniandmebaasi CSV-tõmmisena. Kokku sisaldab prügikast umbes 93 miljonit rida 157 tabelis. Kuigi mõned neist tabelitest sisaldavad põhiandmeid, nagu artistid, sündmused, salvestised, väljalasked või lood, teised linkide tabelid — salvestada seoseid artistide ja salvestiste, teiste artistide või väljaannete jne vahel... Need näitavad andmekogumi graafikustruktuuri. Andmestiku RDF-kolmikteks teisendamisel saime ligikaudu 500 miljonit eksemplari.

Tuginedes projektipartnerite kogemustele ja muljetele, kellega koos töötame, tutvustame seadet, milles seda teadmistebaasi kasutatakse uue teabe hankimiseks. Lisaks eeldame, et seda uuendatakse regulaarselt, lisades näiteks uusi väljalaseid või värskendades grupiliikmeid.

reguleerimine

Nagu oodatud, on Amazon Neptune'i installimine lihtne. Ta on üsna detailne dokumenteeritud. Graafikuandmebaasi saate käivitada vaid mõne klõpsuga. Kui aga rääkida täpsemast konfiguratsioonist, vajalikku teavet raske leida. Seetõttu tahame osutada ühele konfiguratsiooniparameetrile.

Esimesed muljed Amazon Neptune'ist
Parameetrirühmade seadistamise ekraanipilt

Amazon ütleb, et Neptune keskendub madala latentsusega tehingute töökoormustele, mistõttu on päringu vaikeaegu 120 sekundit. Oleme aga katsetanud paljusid analüütilisi kasutusjuhtumeid, mille puhul saavutasime regulaarselt selle piiri. Seda ajalõpu saab muuta, luues Neptune'i jaoks uue parameetrirühma ja seadistus neptune_query_timeout vastav piirang.

Andmete laadimine

Allpool arutame üksikasjalikult, kuidas laadisime MusicBrainzi andmed Neptune'i.

Suhted kolmekesi

Esiteks teisendasime MusicBrainzi andmed RDF-i kolmikuteks. Seetõttu määratlesime iga tabeli jaoks malli, mis määratleb, kuidas iga veerg on kolmikus esitatud. Selles näites on esitajate tabeli iga rida vastendatud kaheteistkümnele RDF-kolmikule.

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

hulgiüleslaadimine

Soovitatav viis suurte andmemahtude laadimiseks Neptune'i on hulgiüleslaadimine S3 kaudu. Pärast kolmekordsete failide üleslaadimist S3-sse alustate üleslaadimist POST-i päringu abil. Meie puhul kulus 24 miljoni kolmiku jaoks umbes 500 tundi. Ootasime, et see on kiirem.

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

Selle pika protsessi vältimiseks iga kord, kui Neptune'i käivitame, otsustasime taastada eksemplari hetktõmmisest, kus need kolmikud olid juba laaditud. Hetketõmmise järgi jooksmine on oluliselt kiirem, kuid kulub siiski umbes tund, kuni Neptune on päringute jaoks saadaval.

Algselt kolmikute Neptuunisse laadimisel ilmnes meil mitmesuguseid vigu.

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

Mõned neist olid sõelumisvead, nagu ülal näidatud. Tänaseks pole me ikka veel aru saanud, mis täpselt valesti läks. Siin aitaks kindlasti veidi rohkem detaile. See viga ilmnes ligikaudu 1% sisestatud kolmikute puhul. Kuid mis puudutab Neptune'i testimist, nõustusime tõsiasjaga, et töötame ainult 99% MusicBrainzi teabest.

Kuigi see on SPARQL-i tuttavatele inimestele lihtne, pidage meeles, et RDF-i kolmikud peavad olema varustatud selgesõnaliste andmetüüpidega, mis võivad jällegi põhjustada vigu.

Voogesituse allalaadimine

Nagu eespool mainitud, ei taha me Neptune'i kasutada staatilise andmehoidlana, vaid pigem paindliku ja areneva teadmistebaasina. Seega pidime leidma viise uute kolmikute juurutamiseks, kui teadmistebaas muutub, näiteks kui ilmub uus album või kui tahame tuletatud teadmisi realiseerida.

Neptune toetab sisendoperaatoreid nii töötlemata kui ka valimipõhiste SPARQL-päringute kaudu. Mõlemat lähenemisviisi käsitleme allpool.

Üks meie eesmärke oli andmete sisestamine voogedastusviisis. Kaaluge albumi väljaandmist uues riigis. MusicBrainzi vaatenurgast tähendab see, et albumeid, singleid, EP-sid jne sisaldava väljalaske puhul lisatakse tabelisse uus kirje vabastamise riik. RDF-is sobitame selle teabe kahe uue kolmikuga.

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

Teine eesmärk oli saada graafikult uusi teadmisi. Oletame, et tahame saada iga artisti oma karjääri jooksul avaldatud väljaannete arvu. Selline päring on üsna keeruline ja võtab Neptuunis aega üle 20 minuti, seega peame tulemuse materialiseerima, et neid uusi teadmisi mõnes teises päringus uuesti kasutada. Seega lisame selle teabega kolmikud graafikule tagasi, sisestades alampäringu tulemuse.

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
 
}

Üksikute kolmikute lisamine graafikule võtab aega paar millisekundit, samas kui alampäringu tulemuse sisestamise täitmisaeg sõltub alampäringu enda täitmisajast.

Kuigi me seda sageli ei kasutanud, võimaldab Neptune eemaldada ka näidiste või selgesõnaliste andmete põhjal kolmikuid, mida saab kasutada teabe värskendamiseks.

SPARQL päringud

Tutvustades eelmist alamnäidist, mis tagastab iga artisti väljaannete arvu, oleme juba tutvustanud esimest tüüpi päringut, millele soovime Neptune'i abil vastata. Päringu koostamine Neptune'is on lihtne – saatke SPARQL-i lõpp-punktile POST-i päring, nagu allpool näidatud:

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

Lisaks oleme rakendanud päringu, mis tagastab artisti profiili, mis sisaldab teavet tema nime, vanuse või päritoluriigi kohta. Pidage meeles, et esinejad võivad olla üksikisikud, ansamblid või orkestrid. Lisaks täiendame neid andmeid artistide aasta jooksul välja antud väljaannete arvu kohta. Sooloartistide puhul lisame ka teavet bändide kohta, kus artist igal aastal osales.

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

Sellise päringu keerukuse tõttu saime punktpäringuid sooritada ainult konkreetse artisti, näiteks Elton Johni, kohta, kuid mitte kõigi artistide kohta. Tundub, et Neptune ei optimeeri sellist päringut, jättes filtrid alamvalikutesse. Seetõttu tuleb iga valik artistinime järgi käsitsi filtreerida.

Neptuunil on nii tunni- kui ka I/O-tasud. Testimiseks kasutasime minimaalset Neptune'i eksemplari, mis maksab 0,384 dollarit tunnis. Ülaltoodud päringu puhul, mis arvutab ühe töötaja profiili, nõuab Amazon meilt kümneid tuhandeid I/O toiminguid, mis tähendab 0.02 dollari suurust kulu.

Väljund

Esiteks peab Amazon Neptune suurema osa oma lubadustest. Hallatava teenusena on see graafikuandmebaas, mida on äärmiselt lihtne installida ja mida saab käivitada ilma palju konfigureerimata. Siin on meie viis peamist leidu:

  • Hulgiüleslaadimine on lihtne, kuid aeglane. Kuid see võib muutuda keeruliseks veateadetega, mis pole eriti kasulikud.
  • Voogesituse allalaadimine toetab kõike, mida ootasime, ja see oli üsna kiire
  • Päringud on lihtsad, kuid mitte piisavalt interaktiivsed analüütiliste päringute käitamiseks
  • SPARQL-i päringuid tuleb optimeerida käsitsi
  • Amazoni makseid on raske hinnata, kuna SPARQL-i päringuga skannitud andmete hulka on raske hinnata.

See on kõik. Registreeruge tasuta veebiseminar teemal "Koormuse tasakaalustamine".


Allikas: www.habr.com

Lisa kommentaar