Agurra, Khabrovskeko bizilagunak. Ikastaroaren hasierari begira
Gustuko ditugun erabilera kasu askotan
Zergatik behar genuen Amazon Neptune
Datu-base grafikoek oso konektatutako datu-multzoak beren baliokide erlazionalak baino hobeto kudeatuko dituztela agintzen dute. Horrelako datu-multzoetan, informazio garrantzitsua objektuen arteko harremanetan gordetzen da normalean. Neptune probatzeko datu irekiko proiektu harrigarri bat erabili dugu
MusicBrainz datu-multzoa datu-base erlazional baten CSV iraulketa gisa eskaintzen da. Guztira, zabortegiak 93 milioi errenkada inguru ditu 157 taulatan. Taula horietako batzuek oinarrizko datuak dituzten arren, hala nola, artistak, gertaerak, grabaketak, argitalpenak edo pistak, beste batzuk lotu taulak — Artisten eta grabazioen arteko harremanak gordetzeko, beste artista edo argitalpenen artean, etab... Datu multzo baten egitura grafikoa erakusten dute. Datu-multzoa RDF hirukoitz bihurtzean, gutxi gorabehera 500 milioi instantzia lortu genituen.
Lan egiten dugun proiektuko bazkideen esperientzia eta inpresioak oinarri hartuta, ezagutza-oinarri hori informazio berria lortzeko erabiltzen den ingurune bat aurkezten dugu. Horrez gain, aldian-aldian eguneratzea espero dugu, adibidez, bertsio berriak gehituz edo taldeko kideak eguneratuz.
doikuntza
Espero bezala, Amazon Neptune instalatzea erraza da. Nahiko zehatza da
Parametro-taldeen konfigurazio-argazkia
Amazonek dioenez, Neptunek latentzia baxuko lan karga transakzionaletan zentratzen da, eta horregatik eskaeraren denbora-muga lehenetsia 120 segundokoa da. Hala ere, muga horretara aldian-aldian iristen ginen erabilera analitiko asko probatu ditugu. Denbora-muga hori Neptunerako parametro-talde berri bat sortuz eta konfiguratuz alda daiteke neptune_query_timeout
dagokion murrizketa.
Datuak kargatzen
Jarraian, MusicBrainz-en datuak Neptune-ra nola kargatu genituen zehatz-mehatz eztabaidatuko dugu.
Harremanak hirunaka
Lehenik eta behin, MusicBrainz datuak RDF hirukoitzetan bihurtu ditugu. Horregatik, taula bakoitzerako, zutabe bakoitza hirukoitzean nola irudikatzen den definitzen duen txantiloi bat definitu dugu. Adibide honetan, interpretatzaileen taulako errenkada bakoitza hamabi RDF hirukoitzekin mapatzen da.
<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> .
kargatze masiboa
Neptune-n datu kopuru handiak kargatzeko iradokitako modua S3 bidez kargatzeko prozesua da. Zure hirukoitzak fitxategiak S3ra kargatu ondoren, POST eskaera erabiliz kargatzen hasiko zara. Gure kasuan, 24 ordu inguru behar izan zituen 500 milioi hirukoteentzat. azkarragoa izango zela espero genuen.
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"
}'
Neptune abiarazten dugun bakoitzean prozesu luze hau saihesteko, hirukote hauek jada kargatuta zeuden instantzia batetik berrezartzea erabaki genuen. Argazki batetik ateratzea nabarmen azkarragoa da, baina hala ere ordubete inguru behar da Neptune eskaerak egiteko erabilgarri egon arte.
Hasieran hirukoteak Neptuno-n kargatzean, hainbat akats aurkitu genituen.
{
"errorCode" : "PARSING_ERROR",
"errorMessage" : "Content after '.' is not allowed",
"fileName" : [...],
"recordNum" : 25
}
Horietako batzuk analisi-erroreak ziren, goian erakutsi bezala. Orain arte, oraindik ez dugu asmatu zer gertatu den une honetan. Xehetasun apur bat gehiago lagunduko luke hemen. Errore hau txertatutako hirukoteen %1ean gertatu da gutxi gorabehera. Baina Neptune probatzeari dagokionez, onartu genuen MusicBrainz-en informazioaren %99arekin bakarrik lan egiten dugula.
Nahiz eta SPARQL ezagutzen duten pertsonentzat erraza den, kontuan izan RDF hirukoitzak datu-mota esplizituekin ohartarazi behar direla, eta horrek akatsak sor ditzake berriro.
Streaming deskarga
Goian esan bezala, ez dugu Neptune datu-biltegi estatiko gisa erabili nahi, ezagutza-base malgu eta eboluzional gisa baizik. Beraz, ezagutza-basea aldatzen denean hirukoitz berriak sartzeko moduak bilatu behar genituen, adibidez album berri bat argitaratzen denean edo ezagutza eratorria gauzatu nahi dugunean.
Neptunek sarrerako operadoreak onartzen ditu SPARQL kontsulten bidez, bai gordinak bai laginetan oinarritutakoak. Jarraian bi ikuspegiak aztertuko ditugu.
Gure helburuetako bat datuak streaming moduan sartzea zen. Demagun album bat herrialde berri batean kaleratzea. MusicBrainzen ikuspuntutik, horrek esan nahi du diskoak, singleak, EP-ak eta abar biltzen dituen bertsio baterako sarrera berri bat gehitzen dela taulara. askapen-herrialdea. RDFn, informazio hori bi hirukoitz berrirekin lotzen dugu.
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> };
Beste helburu bat grafikotik ezagutza berriak lortzea zen. Demagun artista bakoitzak bere ibilbidean argitaratu dituen kaleratze kopurua lortu nahi dugula. Kontsulta bat nahiko konplexua da eta 20 minutu baino gehiago behar ditu Neptunon, beraz, emaitza gauzatu behar dugu ezagutza berri hori beste kontsulta batzuetan berrerabili ahal izateko. Beraz, informazio honekin hirukoiak gehitzen ditugu grafikoan, azpikontsultaren emaitza sartuz.
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
}
Grafikoari hirukoitz bakarrak gehitzeak milisegundo batzuk behar ditu, azpikontsulta baten emaitza txertatzeko exekuzio-denbora azpikontsulta beraren exekuzio-denboraren araberakoa den bitartean.
Askotan erabili ez genuen arren, Neptunek laginetan edo datu esplizituetan oinarritutako hirukoteak kentzeko aukera ere ematen du, informazioa eguneratzeko erabil daitezkeenak.
SPARQL kontsultak
Aurreko azpilagina sartuz, artista bakoitzaren kaleratze kopurua itzultzen duena, dagoeneko sartu dugu Neptune erabiliz erantzun nahi dugun lehen kontsulta mota. Neptune-n kontsulta bat sortzea erraza da - bidali POST eskaera bat SPARQL amaierako puntura, behean erakusten den moduan:
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
Gainera, artistaren profila itzultzen duen kontsulta bat ezarri dugu, bere izenari, adinari edo jatorrizko herrialdeari buruzko informazioa jasotzen duena. Kontuan izan interpreteak norbanakoak, taldeak edo orkestrak izan daitezkeela. Horrez gain, datu hauek urtean zehar artistek kaleratu dituzten kaleratze-kopuruari buruzko informazioarekin osatzen dugu. Bakarlarientzat, artistak urtero parte hartu zuen taldeei buruzko informazioa ere gehitzen dugu.
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)
}
Kontsulta baten konplexutasuna dela eta, artista jakin baterako soilik egin genitzake puntu-kontsultak, Elton John adibidez, baina ez artista guztientzat. Neptunok ez dirudi horrelako kontsulta bat optimizatzen duenik iragazkiak azpihautaketetan jareginez. Hori dela eta, aukeraketa bakoitza eskuz iragazi behar da artistaren izenaren arabera.
Neptunek orduko eta I/O kargak ditu. Gure probak egiteko, gutxieneko Neptune instantzia erabili dugu, 0,384 $ orduko balio duena. Goiko kontsultaren kasuan, langile bakar baten profila kalkulatzen duena, Amazonek hamarnaka mila I/O eragiketa kobratzen dizkigu, 0.02 $-ko kostua suposatzen duena.
Irteera
Lehenik eta behin, Amazon Neptunek bere promesa gehienak betetzen ditu. Kudeatutako zerbitzu gisa, oso erraz instalatzen den datu-base grafikoa da eta konfigurazio handirik gabe martxan egon daitekeena. Hona hemen gure bost aurkikuntza nagusiak:
- Masakako karga erraza baina motela da. Baina konplikatu egin daiteke oso lagungarriak ez diren errore-mezuekin.
- Streaming deskargatzeak espero genuen guztia onartzen du eta nahiko azkarra izan zen
- Kontsultak sinpleak dira, baina ez dira nahikoa interaktiboak kontsulta analitikoak egiteko
- SPARQL kontsultak eskuz optimizatu behar dira
- Amazon-en ordainketak zenbatesten zailak dira, zaila baita SPARQL kontsulta batek eskaneatutako datu kopurua kalkulatzea.
Hori da dena. Izena eman
Iturria: www.habr.com