Tervitused, Habrovski elanikud. Kursuse alguse ootuses
Paljudel kasutusjuhtudel, mis meile meeldivad
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
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
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
Allikas: www.habr.com