Eerste indrukke van Amazon Neptunus

Saluut, Khabrovsk inwoners. In afwagting van die begin van die kursus "AWS vir ontwikkelaars" Ons het 'n vertaling van interessante materiaal voorberei.

Eerste indrukke van Amazon Neptunus

In baie gebruik gevalle waarvan ons hou bakdataSoos ons op ons kliënte se webwerwe sien, is relevante inligting versteek in verbindings tussen entiteite, byvoorbeeld wanneer verhoudings tussen gebruikers, afhanklikhede tussen elemente of verbindings tussen sensors ontleed word. Sulke gebruiksgevalle word gewoonlik op 'n grafiek gemodelleer. Amazon het vroeër vanjaar sy nuwe grafiekdatabasis, Neptune, vrygestel. In hierdie pos wil ons ons eerste idees, goeie praktyke en wat mettertyd verbeter kan word deel.

Hoekom ons Amazon Neptune nodig gehad het

Grafiekdatabasisse beloof om hoogs gekoppelde datastelle beter te hanteer as hul relasionele ekwivalente. In sulke datastelle word relevante inligting gewoonlik in verhoudings tussen voorwerpe gestoor. Ons het 'n ongelooflike oop data-projek gebruik om Neptunus te toets MusicBrainz. MusicBrainz versamel elke soort musiekmetadata denkbaar, soos inligting oor kunstenaars, liedjies, albumvrystellings of konserte, asook met wie die kunstenaar agter die liedjie saamgewerk het of wanneer die album in watter land vrygestel is. MusicBrainz kan gesien word as 'n groot netwerk van entiteite wat op een of ander manier met die musiekbedryf verbind is.

Die MusicBrainz-datastel word verskaf as 'n CSV-storting van 'n relasionele databasis. In totaal bevat die stortingsterrein ongeveer 93 miljoen rye in 157 tabelle. Terwyl sommige van hierdie tabelle basiese data bevat soos kunstenaars, gebeurtenisse, opnames, vrystellings of snitte, ander skakel tabelle — stoor verhoudings tussen kunstenaars en opnames, ander kunstenaars of vrystellings, ens... Hulle demonstreer die grafiekstruktuur van 'n datastel. Toe ons die datastel na RDF-drievoudige omskakel, het ons ongeveer 500 miljoen gevalle gekry.

Gebaseer op die ervaring en indrukke van die projekvennote met wie ons saamwerk, bied ons 'n omgewing waarin hierdie kennisbasis gebruik word om nuwe inligting te bekom. Daarbenewens verwag ons dat dit gereeld bygewerk sal word, byvoorbeeld deur nuwe vrystellings by te voeg of groeplede by te werk.

aanpassing

Soos verwag, is die installering van Amazon Neptune eenvoudig. Sy is nogal gedetailleerd gedokumenteer. U kan 'n grafiekdatabasis in slegs 'n paar kliks begin. As dit egter by meer gedetailleerde konfigurasie kom, nodige inligting moeilik om te vind. Daarom wil ons na een konfigurasieparameter wys.

Eerste indrukke van Amazon Neptunus
Konfigurasieskermkiekie vir parametergroepe

Amazon sê Neptune fokus op lae-latency transaksionele werkladings, en daarom is die verstekversoek-time-out 120 sekondes. Ons het egter baie analitiese gebruiksgevalle getoets waarin ons gereeld hierdie limiet bereik het. Hierdie uitteltyd kan verander word deur 'n nuwe parametergroep vir Neptunus en instelling te skep neptune_query_timeout ooreenstemmende beperking.

Laai data

Hieronder sal ons in detail bespreek hoe ons MusicBrainz-data in Neptunus gelaai het.

Verhoudings in drieë

Eerstens het ons die MusicBrainz-data in RDF-drievoudige omgeskakel. Daarom het ons vir elke tabel 'n sjabloon gedefinieer wat definieer hoe elke kolom in die trippel voorgestel word. In hierdie voorbeeld word elke ry van die presteerdertabel na twaalf RDF-drievoudige gekarteer.

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

grootmaat oplaai

Die voorgestelde manier om groot hoeveelhede data in Neptunus te laai, is deur die grootmaat-oplaaiproses via S3. Nadat u u drievoudige lêers na S3 opgelaai het, begin u die oplaai met 'n POST-versoek. In ons geval het dit ongeveer 24 uur geneem vir 500 miljoen drieling. Ons het verwag dat dit vinniger sou wees.

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 hierdie lang proses te vermy elke keer as ons Neptune begin, het ons besluit om die instansie te herstel vanaf 'n momentopname waarin hierdie drieling reeds gelaai is. Dit is aansienlik vinniger om vanaf 'n momentopname te hardloop, maar dit neem steeds ongeveer 'n uur voordat Neptunus vir versoeke beskikbaar is.

Toe ons aanvanklik drieling in Neptunus laai, het ons verskeie foute teëgekom.

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

Sommige van hulle was ontledingsfoute, soos hierbo getoon. Tot op hede het ons op hierdie stadium nog nie uitgepluis wat presies verkeerd geloop het nie. 'n Bietjie meer detail sal beslis hier help. Hierdie fout het voorgekom vir ongeveer 1% van ingevoegde trippels. Maar wat die toetsing van Neptune betref, het ons die feit aanvaar dat ons net met 99% van die inligting van MusicBrainz werk.

Selfs al is dit maklik vir mense wat vertroud is met SPARQL, wees bewus daarvan dat RDF-drievoudige geannoteer moet word met eksplisiete datatipes, wat weer foute kan veroorsaak.

Stroom aflaai

Soos hierbo genoem, wil ons Neptunus nie as 'n statiese datawinkel gebruik nie, maar eerder as 'n buigsame en ontwikkelende kennisbasis. Ons moes dus maniere vind om nuwe drielinge bekend te stel wanneer die kennisbasis verander, byvoorbeeld wanneer 'n nuwe album gepubliseer word of wanneer ons afgeleide kennis wil realiseer.

Neptunus ondersteun insetoperateurs deur SPARQL-navrae, beide rou en monstergebaseer. Ons sal beide benaderings hieronder bespreek.

Een van ons doelwitte was om data op 'n stromende wyse in te voer. Oorweeg dit om 'n album in 'n nuwe land vry te stel. Vanuit MusicBrainz se perspektief beteken dit dat vir 'n vrystelling wat albums, enkelsnitte, EP's, ens. insluit, 'n nuwe inskrywing by die tabel gevoeg word vrylating-land. In RDF pas ons hierdie inligting met twee nuwe drielinge.

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

Nog 'n doelwit was om nuwe kennis uit die grafiek te verkry. Kom ons sê ons wil die aantal vrystellings kry wat elke kunstenaar in hul loopbaan gepubliseer het. So 'n navraag is redelik kompleks en neem meer as 20 minute in Neptunus, so ons moet die resultaat realiseer om hierdie nuwe kennis in 'n ander navraag te hergebruik. Ons voeg dus drievoudige met hierdie inligting terug by die grafiek en voer die resultaat van die subnavraag in.

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
 
}

Die byvoeging van enkele drievoudige by die grafiek neem 'n paar millisekondes, terwyl die uitvoeringstyd vir die invoeging van die resultaat van 'n subnavraag afhang van die uitvoeringstyd van die subnavraag self.

Alhoewel ons dit nie gereeld gebruik het nie, laat Neptunus jou ook toe om drieling te verwyder op grond van monsters of eksplisiete data, wat gebruik kan word om inligting op te dateer.

SPARQL-navrae

Deur die vorige submonster bekend te stel, wat die aantal vrystellings vir elke kunstenaar gee, het ons reeds die eerste tipe navraag bekendgestel wat ons met Neptunus wil beantwoord. Dit is maklik om 'n navraag in Neptunus te bou - stuur 'n POST-versoek na die SPARQL-eindpunt, soos hieronder getoon:

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

Daarbenewens het ons 'n navraag geïmplementeer wat 'n kunstenaarsprofiel terugstuur wat inligting bevat oor hul naam, ouderdom of land van herkoms. Hou in gedagte dat die kunstenaars individue, groepe of orkeste kan wees. Daarbenewens vul ons hierdie data aan met inligting oor die aantal vrystellings wat gedurende die jaar deur kunstenaars vrygestel is. Vir solo-kunstenaars voeg ons ook inligting by oor die bands waaraan kunstenaar elke jaar deelgeneem het.

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

Weens die kompleksiteit van so 'n navraag kon ons slegs puntnavrae vir 'n spesifieke kunstenaar, soos Elton John, uitvoer, maar nie vir alle kunstenaars nie. Dit lyk nie of Neptunus so 'n navraag optimaliseer deur filters in subselecties te laat val nie. Daarom moet elke seleksie handmatig volgens kunstenaarnaam gefiltreer word.

Neptunus het beide uurlikse en per-I/O-heffings. Vir ons toetsing het ons die minimum Neptune-instansie gebruik, wat $0,384/uur kos. In die geval van die navraag hierbo, wat die profiel vir 'n enkele werker bereken, hef Amazon ons tienduisende I/O-operasies, wat 'n koste van $0.02 impliseer.

Output

Eerstens kom Amazon Neptune die meeste van sy beloftes na. As 'n bestuurde diens is dit 'n grafiekdatabasis wat uiters maklik is om te installeer en sonder veel konfigurasie aan die gang kan wees. Hier is ons vyf sleutelbevindings:

  • Grootmaat oplaai is maklik, maar stadig. Maar dit kan ingewikkeld raak met foutboodskappe wat nie baie nuttig is nie.
  • Stroomaflaai ondersteun alles wat ons verwag het en was redelik vinnig
  • Navrae is eenvoudig, maar nie interaktief genoeg om analitiese navrae uit te voer nie
  • SPARQL-navrae moet met die hand geoptimaliseer word
  • Amazon-betalings is moeilik om te skat omdat dit moeilik is om die hoeveelheid data wat deur 'n SPARQL-navraag geskandeer is, te skat.

Dis al. Skryf in vir gratis webinar oor die onderwerp "Lasbalansering".


Bron: will.com

Voeg 'n opmerking