Prvé dojmy z Amazonského Neptúna

Pozdravte, obyvatelia Khabrovska. V očakávaní začiatku kurzu "AWS pre vývojárov" Pripravili sme preklad zaujímavého materiálu.

Prvé dojmy z Amazonského Neptúna

V mnohých prípadoch použitia, ktoré sa nám páčia bakdataAko vidíme na webových stránkach našich klientov, relevantné informácie sú skryté v prepojeniach medzi entitami, napríklad pri analýze vzťahov medzi používateľmi, závislostí medzi prvkami alebo prepojení medzi senzormi. Takéto prípady použitia sú zvyčajne modelované na grafe. Začiatkom tohto roka Amazon zverejnil svoju novú databázu grafov Neptún. V tomto príspevku sa chceme podeliť o naše prvé nápady, osvedčené postupy a to, čo sa dá časom zlepšiť.

Prečo sme potrebovali Amazon Neptún

Databázy grafov sľubujú, že budú spracovať vysoko prepojené množiny údajov lepšie ako ich relačné ekvivalenty. V takýchto súboroch údajov sú relevantné informácie zvyčajne uložené vo vzťahoch medzi objektmi. Na testovanie Neptúna sme použili úžasný projekt otvorených dát MusicBrainz. MusicBrainz zhromažďuje všetky možné hudobné metadáta, ako sú informácie o interpretoch, skladbách, vydaných albumoch alebo koncertoch, ako aj o tom, s kým interpret za skladbou spolupracoval alebo kedy bol album vydaný v ktorej krajine. MusicBrainz možno vnímať ako obrovskú sieť subjektov, ktoré sú nejakým spôsobom spojené s hudobným priemyslom.

Súbor údajov MusicBrainz sa poskytuje ako výpis CSV relačnej databázy. Celkovo obsahuje skládka asi 93 miliónov riadkov v 157 tabuľkách. Zatiaľ čo niektoré z týchto tabuliek obsahujú základné údaje, ako sú umelci, udalosti, nahrávky, vydania alebo skladby, iné odkazové tabuľky — uchovávať vzťahy medzi umelcami a nahrávkami, inými umelcami alebo vydaniami atď... Ukazujú grafovú štruktúru súboru údajov. Pri prevode množiny údajov na trojnásobok RDF sme získali približne 500 miliónov inštancií.

Na základe skúseností a dojmov partnerov projektu, s ktorými spolupracujeme, uvádzame prostredie, v ktorom sa táto báza znalostí využíva na získavanie nových informácií. Okrem toho očakávame, že bude pravidelne aktualizovaný, napríklad pridávaním nových vydaní alebo aktualizáciou členov skupiny.

nastavenie

Ako sa očakávalo, inštalácia Amazon Neptune je jednoduchá. Je dosť podrobná zdokumentované. Databázu grafov môžete spustiť len niekoľkými kliknutiami. Pokiaľ však ide o podrobnejšiu konfiguráciu, potrebné informácie ťažko nájsť. Preto chceme poukázať na jeden konfiguračný parameter.

Prvé dojmy z Amazonského Neptúna
Snímka obrazovky konfigurácie pre skupiny parametrov

Amazon hovorí, že Neptún sa zameriava na transakčné pracovné zaťaženie s nízkou latenciou, a preto je predvolený časový limit požiadavky 120 sekúnd. Testovali sme však mnoho prípadov analytického použitia, v ktorých sme pravidelne dosahovali túto hranicu. Tento časový limit je možné zmeniť vytvorením novej skupiny parametrov pre Neptún a nastavením neptune_query_timeout zodpovedajúce obmedzenie.

Načítavajú sa údaje

Nižšie podrobne rozoberieme, ako sme načítali údaje MusicBrainz do Neptúna.

Vzťahy v trojici

Najprv sme previedli údaje MusicBrainz na trojnásobok RDF. Preto sme pre každú tabuľku definovali šablónu, ktorá definuje, ako je každý stĺpec zastúpený v trojici. V tomto príklade je každý riadok z tabuľky interpretov mapovaný na dvanásť trojíc 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> .

Hromadné nahrávanie

Navrhovaný spôsob načítania veľkého množstva údajov do Neptúna je proces hromadného nahrávania cez S3. Po nahratí vašich trojitých súborov do S3 začnete s nahrávaním pomocou požiadavky POST. V našom prípade to trvalo približne 24 hodín pre 500 miliónov trojíc. Čakali sme, že to bude rýchlejšie.

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

Aby sme sa vyhli tomuto zdĺhavému procesu pri každom spustení Neptúna, rozhodli sme sa obnoviť inštanciu zo snímky, v ktorej už boli tieto trojice načítané. Spustenie zo snímky je výrazne rýchlejšie, ale stále trvá približne hodinu, kým bude Neptún dostupný pre požiadavky.

Pri prvotnom načítavaní trojíc do Neptúna sme narazili na rôzne chyby.

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

Niektoré z nich boli chyby analýzy, ako je uvedené vyššie. Dodnes sme stále neprišli na to, čo presne sa v tomto bode pokazilo. Tu by určite pomohlo trochu viac detailov. Táto chyba sa vyskytla približne u 1 % vložených trojíc. Ale čo sa týka testovania Neptúna, akceptovali sme fakt, že pracujeme len s 99 % informácií od MusicBrainz.

Aj keď je to jednoduché pre ľudí, ktorí poznajú SPARQL, uvedomte si, že trojité RDF musia byť označené explicitnými typmi údajov, čo opäť môže spôsobiť chyby.

Streamovanie na stiahnutie

Ako už bolo spomenuté vyššie, Neptún nechceme používať ako statické úložisko dát, ale skôr ako flexibilnú a vyvíjajúcu sa bázu znalostí. Museli sme teda nájsť spôsoby, ako zaviesť nové trojky, keď sa zmení báza znalostí, napríklad keď vyjde nový album alebo keď chceme zhmotniť odvodené poznatky.

Neptún podporuje vstupné operátory prostredníctvom dopytov SPARQL, a to ako nespracovaných, tak aj na základe vzoriek. Oba prístupy rozoberieme nižšie.

Jedným z našich cieľov bolo zadávať údaje streamovaným spôsobom. Zvážte vydanie albumu v novej krajine. Z pohľadu MusicBrainz to znamená, že pre vydanie, ktoré obsahuje albumy, single, EP atď., sa do tabuľky pridá nový záznam vydanie-krajina. V RDF porovnávame tieto informácie s dvoma novými trojitami.

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

Ďalším cieľom bolo získať nové poznatky z grafu. Povedzme, že chceme získať počet vydaní, ktoré každý umelec vydal počas svojej kariéry. Takýto dopyt je pomerne zložitý a v Neptúne trvá viac ako 20 minút, takže musíme zhmotniť výsledok, aby sme mohli tieto nové poznatky znova použiť v inom dopyte. Do grafu teda pridáme trojičky s touto informáciou späť, pričom zadáme výsledok poddotazu.

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
 
}

Pridanie jednotlivých trojíc do grafu trvá niekoľko milisekúnd, pričom čas vykonania na vloženie výsledku poddotazu závisí od času vykonania samotného poddotazu.

Hoci sme to nepoužívali často, Neptún vám tiež umožňuje odstraňovať triplety na základe vzoriek alebo explicitných údajov, ktoré možno použiť na aktualizáciu informácií.

Dotazy SPARQL

Uvedením predchádzajúcej čiastkovej ukážky, ktorá vracia počet vydaní pre každého interpreta, sme už zaviedli prvý typ dotazu, na ktorý chceme odpovedať pomocou Neptúna. Vytvorenie dotazu v Neptúne je jednoduché – odošlite požiadavku POST na koncový bod SPARQL, ako je uvedené nižšie:

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

Okrem toho sme implementovali dotaz, ktorý vráti profil interpreta s informáciami o jeho mene, veku alebo krajine pôvodu. Majte na pamäti, že účinkujúcimi môžu byť jednotlivci, kapely alebo orchestre. Okrem toho tieto údaje dopĺňame o informácie o počte releasov vydaných umelcami počas roka. Pre sólových interpretov pridávame aj informácie o kapelách, ktorých sa umelec každý rok zúčastnil.

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

Kvôli zložitosti takéhoto dotazu sme mohli vykonať bodové dopyty iba pre konkrétneho interpreta, ako je Elton John, ale nie pre všetkých umelcov. Zdá sa, že Neptún neoptimalizuje takýto dopyt vypustením filtrov do podvýberov. Preto musí byť každý výber manuálne filtrovaný podľa mena interpreta.

Neptún má hodinové poplatky aj poplatky za I/O. Na naše testovanie sme použili minimálnu inštanciu Neptúna, ktorá stojí 0,384 USD za hodinu. V prípade vyššie uvedeného dotazu, ktorý počíta profil pre jedného pracovníka, nám Amazon účtuje desiatky tisíc I/O operácií, čo znamená cenu 0.02 USD.

Výkon

Po prvé, Amazon Neptune dodržiava väčšinu svojich sľubov. Ako riadená služba ide o databázu grafov, ktorá sa veľmi jednoducho inštaluje a môže byť spustená a spustená bez veľkého množstva konfigurácií. Tu je našich päť kľúčových zistení:

  • Hromadné nahrávanie je jednoduché, ale pomalé. Môže sa to však skomplikovať chybovými správami, ktoré nie sú príliš užitočné.
  • Streamovanie podporuje všetko, čo sme očakávali, a bolo pomerne rýchle
  • Dotazy sú jednoduché, ale nie dostatočne interaktívne na spustenie analytických dotazov
  • Dotazy SPARQL musia byť optimalizované manuálne
  • Platby cez Amazon je ťažké odhadnúť, pretože je ťažké odhadnúť množstvo dát naskenovaných dopytom SPARQL.

To je všetko. Zaregistrovať bezplatný webinár na tému „Vyvažovanie záťaže“.


Zdroj: hab.com

Pridať komentár