Ensivaikutelma Amazon Neptunesta

Tervehdys, Habrovskin asukkaat. Kurssin alkua odotellessa "AWS kehittäjille" Olemme laatineet käännöksen mielenkiintoisesta materiaalista.

Ensivaikutelma Amazon Neptunesta

Monissa käyttötapauksissa, joista pidämme bakdataKuten asiakkaidemme verkkosivuilla näemme, olennainen tieto on piilotettu entiteettien välisiin yhteyksiin, esimerkiksi analysoitaessa käyttäjien välisiä suhteita, elementtien välisiä riippuvuuksia tai anturien välisiä yhteyksiä. Tällaiset käyttötapaukset mallinnetaan yleensä graafisesti. Aiemmin tänä vuonna Amazon julkaisi uuden graafitietokantansa, Neptunen. Tässä postauksessa haluamme jakaa ensimmäiset ideamme, hyvät käytännöt ja mitä voidaan parantaa ajan myötä.

Miksi tarvitsimme Amazon Neptunen

Graafitietokannat lupaavat käsitellä pitkälle kytkettyjä tietojoukkoja paremmin kuin niiden relaatiovastaavat. Tällaisissa tietojoukoissa olennaiset tiedot tallennetaan yleensä objektien välisiin suhteisiin. Käytimme hämmästyttävää avoimen datan projektia Neptunen testaamiseen MusicBrainz. MusicBrainz kerää kaikenlaisia ​​kuviteltavissa olevia musiikin metatietoja, kuten tietoja artisteista, kappaleista, albumien julkaisuista tai konserteista sekä siitä, kenen kanssa kappaleen takana oleva artisti teki yhteistyötä tai milloin albumi julkaistiin missäkin maassa. MusicBrainz voidaan nähdä valtavana verkostona kokonaisuuksia, jotka ovat jollain tavalla yhteydessä musiikkiteollisuuteen.

MusicBrainz-tietojoukko toimitetaan relaatiotietokannan CSV-vedostiedostona. Yhteensä vedos sisältää noin 93 miljoonaa riviä 157 taulukossa. Jotkut näistä taulukoista sisältävät perustietoja, kuten artisteja, tapahtumia, tallenteita, julkaisuja tai kappaleita, toiset linkkitaulukot — tallentaa artistien ja äänitteiden, muiden artistien tai julkaisujen välisiä suhteita jne. Ne osoittavat tietojoukon graafisen rakenteen. Muuntaessamme tietojoukon RDF-kolmoisiksi saimme noin 500 miljoonaa esiintymää.

Niiden projektikumppaneiden kokemusten ja vaikutelmien perusteella, joiden kanssa työskentelemme, esittelemme ympäristön, jossa tätä tietopohjaa käytetään uuden tiedon hankkimiseen. Lisäksi odotamme sen päivittyvän säännöllisesti, esimerkiksi lisäämällä uusia julkaisuja tai päivittämällä ryhmän jäseniä.

säätö

Kuten odotettiin, Amazon Neptunen asentaminen on helppoa. Hän on melko yksityiskohtainen dokumentoitu. Voit käynnistää kaaviotietokannan muutamalla napsautuksella. Mutta kun on kyse yksityiskohtaisemmasta kokoonpanosta, tarvittavat tiedot vaikea löytää. Siksi haluamme osoittaa yhteen konfigurointiparametriin.

Ensivaikutelma Amazon Neptunesta
Asetuskuvakaappaus parametriryhmille

Amazon sanoo, että Neptune keskittyy alhaisen latenssin transaktiotyökuormiin, minkä vuoksi pyynnön oletusaikakatkaisu on 120 sekuntia. Olemme kuitenkin testanneet monia analyyttisiä käyttötapauksia, joissa saavutimme tämän rajan säännöllisesti. Tätä aikakatkaisua voidaan muuttaa luomalla uusi parametriryhmä Neptunukselle ja asetukselle neptune_query_timeout vastaava rajoitus.

Ladataan tietoja

Alla keskustelemme yksityiskohtaisesti siitä, kuinka latasimme MusicBrainz-tiedot Neptunukseen.

Suhteet kolmessa

Ensin muunsimme MusicBrainz-tiedot RDF-kolmoisiksi. Siksi määritimme jokaiselle taulukolle mallin, joka määrittää, kuinka kukin sarake esitetään kolmiossa. Tässä esimerkissä jokainen esiintyjätaulukon rivi on kartoitettu kahteentoista RDF-kolmokseen.

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

joukkolataus

Suositeltu tapa ladata suuria tietomääriä Neptunukseen on joukkolatausprosessi S3:n kautta. Kun olet ladannut kolmoistiedostot S3:een, aloitat latauksen POST-pyynnöllä. Meidän tapauksessamme 24 miljoonan kolmosen saamiseen kului noin 500 tuntia. Odotimme sen olevan nopeampi.

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

Välttääksemme tämän pitkän prosessin joka kerta, kun käynnistämme Neptunen, päätimme palauttaa ilmentymän tilannevedosta, jossa nämä kolmiot oli jo ladattu. Tilannekuvasta juokseminen on huomattavasti nopeampaa, mutta kestää silti noin tunnin ennen kuin Neptune on käytettävissä pyyntöjä varten.

Kun alun perin latasimme triplettejä Neptunukseen, kohtasimme erilaisia ​​virheitä.

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

Jotkut niistä olivat jäsennysvirheitä, kuten yllä näkyy. Toistaiseksi emme ole vieläkään selvittäneet, mikä meni pieleen tässä vaiheessa. Vähän tarkempi yksityiskohta auttaisi tässä varmasti. Tämä virhe tapahtui noin 1 %:lla lisätyistä kolmioista. Mutta mitä tulee Neptunen testaamiseen, hyväksyimme sen tosiasian, että käytämme vain 99 % MusicBrainzin tiedoista.

Vaikka tämä on helppoa SPARQL:n tunteville ihmisille, on hyvä muistaa, että RDF-kolmot on merkittävä eksplisiittisillä tietotyypeillä, mikä taas voi aiheuttaa virheitä.

Suoratoiston lataus

Kuten edellä mainittiin, emme halua käyttää Neptunea staattisena tietovarastona, vaan joustavana ja kehittyvänä tietopohjana. Joten meidän piti löytää tapoja ottaa käyttöön uusia kolmioita tietopohjan muuttuessa, esimerkiksi kun uusi albumi julkaistaan ​​tai kun halutaan materialisoida johdettua tietoa.

Neptune tukee syöttöoperaattoreita SPARQL-kyselyillä, sekä raaka- että näytepohjaisilla. Keskustelemme molemmista lähestymistavoista alla.

Yksi tavoitteistamme oli syöttää dataa suoratoistona. Harkitse albumin julkaisemista uudessa maassa. MusicBrainzin näkökulmasta tämä tarkoittaa, että julkaisulle, joka sisältää albumeja, singlejä, EP:itä jne., taulukkoon lisätään uusi merkintä julkaisumaa. RDF:ssä yhdistämme nämä tiedot kahteen uuteen kolmioon.

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

Toinen tavoite oli saada uutta tietoa graafista. Oletetaan, että haluamme saada kunkin artistin uransa aikana julkaisemien julkaisujen määrän. Tällainen kysely on melko monimutkainen ja kestää yli 20 minuuttia Neptunuksessa, joten meidän on realisoitava tulos, jotta voimme käyttää tätä uutta tietoa jossain muussa kyselyssä. Joten lisäämme kolmiot näillä tiedoilla takaisin kaavioon syöttämällä alikyselyn tuloksen.

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
 
}

Yksittäisten kolmosten lisääminen kuvaajaan vie muutaman millisekunnin, kun taas alikyselyn tuloksen lisäämisen suoritusaika riippuu itse alikyselyn suoritusajasta.

Vaikka emme käyttäneet sitä usein, Neptune mahdollistaa myös kolmosien poistamisen näytteiden tai eksplisiittisten tietojen perusteella, joita voidaan käyttää tietojen päivittämiseen.

SPARQL-kyselyt

Esittelemällä edellisen alinäytteen, joka palauttaa kunkin artistin julkaisujen määrän, olemme jo ottaneet käyttöön ensimmäisen tyyppisen kyselyn, johon haluamme vastata Neptunella. Kyselyn rakentaminen Neptunessa on helppoa - lähetä POST-pyyntö SPARQL-päätepisteeseen alla olevan kuvan mukaisesti:

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

Lisäksi olemme ottaneet käyttöön kyselyn, joka palauttaa artistiprofiilin, joka sisältää tiedot heidän nimestään, iästään tai alkuperämaasta. Muista, että esiintyjät voivat olla yksilöitä, bändejä tai orkestereita. Lisäksi täydennämme tietoja artistien vuoden aikana julkaisemien julkaisujen määrästä. Sooloartisteille lisäämme myös tiedot bändeistä, joihin artisti osallistui vuosittain.

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

Tällaisen kyselyn monimutkaisuuden vuoksi pystyimme suorittamaan pistekyselyitä vain tietylle artistille, kuten Elton Johnille, mutta emme kaikille artisteille. Neptune ei näytä optimoivan tällaista kyselyä pudottamalla suodattimia osavalintoihin. Siksi jokainen valinta on suodatettava manuaalisesti esittäjän nimen mukaan.

Neptunessa on sekä tunti- että I/O-lataukset. Testauksessamme käytimme minimin Neptune-instanssia, joka maksaa 0,384 dollaria/tunti. Yllä olevassa kyselyssä, joka laskee profiilin yhdelle työntekijälle, Amazon veloittaa meiltä kymmeniä tuhansia I/O-operaatioita, mikä tarkoittaa 0.02 dollarin kustannuksia.

johtopäätös

Ensinnäkin Amazon Neptune pitää suurimman osan lupauksistaan. Hallittuna palveluna se on kaaviotietokanta, joka on erittäin helppo asentaa ja joka voidaan ottaa käyttöön ilman suuria määrityksiä. Tässä on viisi tärkeintä löytöämme:

  • Joukkolataus on helppoa, mutta hidasta. Mutta se voi olla monimutkaista virheilmoituksilla, jotka eivät ole kovin hyödyllisiä.
  • Suoratoistolataus tukee kaikkea mitä odotimme ja oli melko nopea
  • Kyselyt ovat yksinkertaisia, mutta eivät tarpeeksi interaktiivisia analyyttisten kyselyjen suorittamiseen
  • SPARQL-kyselyt on optimoitava manuaalisesti
  • Amazon-maksuja on vaikea arvioida, koska SPARQL-kyselyllä skannatun tiedon määrää on vaikea arvioida.

Siinä kaikki. Ilmottautua ilmainen webinaari aiheesta "Kuormituksen tasapainottaminen".


Lähde: will.com

Lisää kommentti