Sveiciens, Habrovskas iedzÄ«votÄji. Gaidot kursu sÄkumu
Daudzos lietoŔanas gadījumos, kas mums patīk
KÄpÄc mums bija vajadzÄ«gs Amazon Neptune
Grafu datu bÄzes sola labÄk apstrÄdÄt ļoti savienotas datu kopas nekÄ to relÄciju ekvivalenti. Å ÄdÄs datu kopÄs attiecÄ«gÄ informÄcija parasti tiek glabÄta attiecÄ«bÄs starp objektiem. MÄs izmantojÄm pÄrsteidzoÅ”u atvÄrto datu projektu, lai pÄrbaudÄ«tu NeptÅ«nu
MusicBrainz datu kopa tiek nodroÅ”inÄta kÄ relÄciju datu bÄzes CSV izgÄztuve. KopumÄ izgÄztuvÄ ir aptuveni 93 miljoni rindu 157 tabulÄs. Lai gan dažas no Ŕīm tabulÄm satur pamatdatus, piemÄram, mÄksliniekus, notikumus, ierakstus, izlaidumus vai ierakstus, citi saiÅ”u tabulas ā saglabÄt attiecÄ«bas starp mÄksliniekiem un ierakstiem, citiem mÄksliniekiem vai izlaidumiem utt... Tie demonstrÄ datu kopas grafiku struktÅ«ru. PÄrvÄrÅ”ot datu kopu RDF trÄ«skÄrÅ”os, mÄs ieguvÄm aptuveni 500 miljonus gadÄ«jumu.
Balstoties uz to projekta partneru pieredzi un iespaidiem, ar kuriem sadarbojamies, mÄs piedÄvÄjam uzstÄdÄ«jumu, kurÄ Å”Ä« zinÄÅ”anu bÄze tiek izmantota jaunas informÄcijas iegÅ«Å”anai. TurklÄt mÄs sagaidÄm, ka tas tiks regulÄri atjauninÄts, piemÄram, pievienojot jaunus izdevumus vai atjauninot grupas dalÄ«bniekus.
koriÄ£ÄÅ”ana
KÄ gaidÄ«ts, Amazon Neptune instalÄÅ”ana ir vienkÄrÅ”a. ViÅa ir diezgan detalizÄta
Parametru grupu konfigurÄcijas ekrÄnuzÅÄmums
Amazon saka, ka Neptune koncentrÄjas uz zema latentuma darÄ«jumu darba slodzi, tÄpÄc noklusÄjuma pieprasÄ«juma noildze ir 120 sekundes. TomÄr mÄs esam pÄrbaudÄ«juÅ”i daudzus analÄ«tiskus lietoÅ”anas gadÄ«jumus, kuros mÄs regulÄri sasniegÄm Å”o robežu. Å o taimautu var mainÄ«t, izveidojot jaunu NeptÅ«na parametru grupu un iestatÄ«jumu neptune_query_timeout
atbilstoŔs ierobežojums.
Notiek datu ielÄde
TÄlÄk mÄs detalizÄti apspriedÄ«sim, kÄ mÄs ielÄdÄjÄm MusicBrainz datus Neptune.
AttiecÄ«bas trijatÄ
PirmkÄrt, mÄs pÄrveidojÄm MusicBrainz datus RDF trÄ«skÄrÅ”os. TÄpÄc katrai tabulai mÄs definÄjÄm veidni, kas nosaka, kÄ katra kolonna tiek attÄlota trÄ«skÄrÅ”Ä. Å ajÄ piemÄrÄ katra izpildÄ«tÄju tabulas rinda ir kartÄta uz divpadsmit RDF trÄ«skÄrÅ”iem.
<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> .
lielapjoma augÅ”upielÄde
Ieteicamais veids, kÄ ielÄdÄt lielu datu apjomu Neptune, ir lielapjoma augÅ”upielÄdes process, izmantojot S3. PÄc trÄ«skÄrÅ”o failu augÅ”upielÄdes S3 sÄciet augÅ”upielÄdi, izmantojot POST pieprasÄ«jumu. MÅ«su gadÄ«jumÄ 24 miljoniem trÄ«nÄ«Å”u bija nepiecieÅ”amas aptuveni 500 stundas. MÄs gaidÄ«jÄm, ka tas bÅ«s ÄtrÄk.
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"
}'
Lai izvairÄ«tos no Ŕī ilgstoÅ”Ä procesa ikreiz, kad palaižam Neptune, mÄs nolÄmÄm atjaunot gadÄ«jumu no momentuzÅÄmuma, kurÄ Å”ie tripleti jau bija ielÄdÄti. DarbinÄÅ”ana no momentuzÅÄmuma ir ievÄrojami ÄtrÄka, taÄu joprojÄm ir nepiecieÅ”ama aptuveni stunda, lÄ«dz Neptune ir pieejams pieprasÄ«jumiem.
SÄkotnÄji ielÄdÄjot tripletus NeptÅ«nÄ, mÄs saskÄrÄmies ar dažÄdÄm kļūdÄm.
{
"errorCode" : "PARSING_ERROR",
"errorMessage" : "Content after '.' is not allowed",
"fileName" : [...],
"recordNum" : 25
}
Dažas no tÄm bija parsÄÅ”anas kļūdas, kÄ parÄdÄ«ts iepriekÅ”. LÄ«dz Å”im mÄs joprojÄm neesam sapratuÅ”i, kas tieÅ”i Å”ajÄ brÄ«dÄ« nogÄja greizi. Å eit noteikti noderÄtu nedaudz sÄ«kÄka informÄcija. Å Ä« kļūda radÄs aptuveni 1% ievietoto trÄ«skÄrÅ”u. Bet, kas attiecas uz Neptune testÄÅ”anu, mÄs pieÅÄmÄm faktu, ka strÄdÄjam tikai ar 99% no MusicBrainz informÄcijas.
Lai gan cilvÄkiem, kas pÄrzina SPARQL, tas ir viegli, Åemiet vÄrÄ, ka RDF trÄ«skÄrÅ”iem ir jÄbÅ«t anotÄtiem ar skaidriem datu tipiem, kas atkal var izraisÄ«t kļūdas.
StraumÄÅ”anas lejupielÄde
KÄ minÄts iepriekÅ”, mÄs nevÄlamies izmantot Neptune kÄ statisku datu krÄtuvi, bet gan kÄ elastÄ«gu un attÄ«stoÅ”u zinÄÅ”anu bÄzi. TÄpÄc mums bija jÄatrod veidi, kÄ ieviest jaunus trÄ«skÄrÅ”us, kad mainÄs zinÄÅ”anu bÄze, piemÄram, kad tiek publicÄts jauns albums vai kad mÄs vÄlamies materializÄt iegÅ«tÄs zinÄÅ”anas.
Neptune atbalsta ievades operatorus, izmantojot SPARQL vaicÄjumus, gan neapstrÄdÄtos, gan izlases veidÄ. TÄlÄk mÄs apspriedÄ«sim abas pieejas.
Viens no mÅ«su mÄrÄ·iem bija ievadÄ«t datus straumÄÅ”anas veidÄ. Apsveriet iespÄju izdot albumu jaunÄ valstÄ«. No MusicBrainz viedokļa tas nozÄ«mÄ, ka izdevumam, kurÄ ir albumi, singli, EP utt., tabulai tiek pievienots jauns ieraksts. atbrÄ«voÅ”anas valsts. RDF mÄs salÄ«dzinÄm Å”o informÄciju ar diviem jauniem trÄ«skÄrÅ”iem.
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> };
VÄl viens mÄrÄ·is bija iegÅ«t jaunas zinÄÅ”anas no grafika. PieÅemsim, ka mÄs vÄlamies iegÅ«t katra izpildÄ«tÄja publicÄto izdevumu skaitu savas karjeras laikÄ. Å Äds vaicÄjums ir diezgan sarežģīts un aizÅem vairÄk nekÄ 20 minÅ«tes NeptÅ«nÄ, tÄpÄc mums ir jÄrealizÄ rezultÄts, lai atkÄrtoti izmantotu Ŕīs jaunÄs zinÄÅ”anas kÄdÄ citÄ vaicÄjumÄ. TÄtad mÄs pievienojam trÄ«skÄrÅ”us ar Å”o informÄciju atpakaļ grafikÄ, ievadot apakÅ”vaicÄjuma rezultÄtu.
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
}
AtseviŔķu trÄ«skÄrÅ”u pievienoÅ”ana diagrammai aizÅem dažas milisekundes, savukÄrt izpildes laiks apakÅ”vaicÄjuma rezultÄta ievietoÅ”anai ir atkarÄ«gs no paÅ”a apakÅ”vaicÄjuma izpildes laika.
Lai gan mÄs to neizmantojÄm bieži, Neptune ļauj arÄ« noÅemt tripletus, pamatojoties uz paraugiem vai skaidriem datiem, kurus var izmantot informÄcijas atjauninÄÅ”anai.
SPARQL vaicÄjumi
IevieÅ”ot iepriekÅ”Äjo apakÅ”izlasi, kas atgriež katra izpildÄ«tÄja izlaidumu skaitu, mÄs jau esam ieviesuÅ”i pirmo vaicÄjuma veidu, uz kuru vÄlamies atbildÄt, izmantojot Neptune. VaicÄjuma izveide programmÄ Neptune ir vienkÄrÅ”a ā nosÅ«tiet POST pieprasÄ«jumu uz SPARQL galapunktu, kÄ parÄdÄ«ts tÄlÄk:
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
TurklÄt esam ieviesuÅ”i vaicÄjumu, kas atgriež izpildÄ«tÄja profilu, kurÄ ir informÄcija par viÅa vÄrdu, vecumu vai izcelsmes valsti. Å emiet vÄrÄ, ka izpildÄ«tÄji var bÅ«t privÄtpersonas, grupas vai orÄ·estri. Papildus papildinÄm Å”os datus ar informÄciju par mÄkslinieku izdoto izdevumu skaitu gada laikÄ. Solo mÄksliniekiem pievienojam arÄ« informÄciju par grupÄm, kurÄs mÄkslinieks piedalÄ«jÄs katru gadu.
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)
}
Å Äda vaicÄjuma sarežģītÄ«bas dÄļ punktu vaicÄjumus varÄjÄm veikt tikai konkrÄtam izpildÄ«tÄjam, piemÄram, Eltonam Džonam, bet ne visiem mÄksliniekiem. Å Ä·iet, ka NeptÅ«ns neoptimizÄ Å”Ädu vaicÄjumu, nometot filtrus apakÅ”atlasÄs. TÄpÄc katra atlase ir manuÄli jÄfiltrÄ pÄc izpildÄ«tÄja vÄrda.
NeptÅ«nam ir gan stundas, gan I/O maksas. MÅ«su testÄÅ”anai mÄs izmantojÄm minimÄlo Neptune instanci, kas maksÄ 0,384 USD stundÄ. IepriekÅ”ÄjÄ vaicÄjumÄ, kas aprÄÄ·ina profilu vienam darbiniekam, Amazon iekasÄ no mums desmitiem tÅ«kstoÅ”u I/O operÄciju, kas nozÄ«mÄ 0.02 ASV dolÄru izmaksas.
secinÄjums
PirmkÄrt, Amazon Neptune pilda lielÄko daļu savu solÄ«jumu. KÄ pÄrvaldÄ«ts pakalpojums tÄ ir grafiku datu bÄze, kuru ir ļoti viegli instalÄt un kuru var izveidot un darboties bez lielas konfigurÄcijas. Å eit ir mÅ«su pieci galvenie atklÄjumi:
- Lielapjoma augÅ”upielÄde ir vienkÄrÅ”a, bet lÄna. TaÄu to var sarežģīt kļūdas ziÅojumi, kas nav Ä«paÅ”i noderÄ«gi.
- StraumÄÅ”anas lejupielÄde atbalsta visu, ko mÄs gaidÄ«jÄm, un tÄ bija diezgan Ätra
- VaicÄjumi ir vienkÄrÅ”i, taÄu nav pietiekami interaktÄ«vi, lai izpildÄ«tu analÄ«tiskos vaicÄjumus
- SPARQL vaicÄjumi ir jÄoptimizÄ manuÄli
- Amazon maksÄjumus ir grÅ«ti novÄrtÄt, jo ir grÅ«ti novÄrtÄt ar SPARQL vaicÄjumu skenÄto datu apjomu.
Tas ir viss. ReÄ£istrÄties
Avots: www.habr.com