Pozdravte, obyvatelia Khabrovska. V očakávaní začiatku kurzu
V mnohých prípadoch použitia, ktoré sa nám páčia
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
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á
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ť
Zdroj: hab.com