Amazon Neptuneren lehen inpresioak

Agurra, Khabrovskeko bizilagunak. Ikastaroaren hasierari begira "Garatzaileentzako AWS" Material interesgarriaren itzulpena prestatu dugu.

Amazon Neptuneren lehen inpresioak

Gustuko ditugun erabilera kasu askotan bakdataGure bezeroen webguneetan ikusten dugunez, informazio garrantzitsua ezkutatzen da entitateen arteko konexioetan, adibidez erabiltzaileen arteko harremanak, elementuen arteko mendekotasunak edo sentsoreen arteko konexioak aztertzean. Erabilera-kasu horiek grafiko batean modelatu ohi dira. Urte hasieran, Amazonek bere datu-base grafiko berria kaleratu zuen, Neptune. Post honetan gure lehen ideiak, praktika onak eta denborarekin hobetu daitekeena partekatu nahi dugu.

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. MusicBrainz-ek imajina daitezkeen musika-metadatu guztiak biltzen ditu, hala nola, artistei, abestiei, album-argitaratzeei edo kontzertuei buruzko informazioa, baita abestiaren atzean dagoen artistak kolaboratu duen edo diskoa zein herrialdetan argitaratu den ere. MusicBrainz musikaren industriari nolabait lotuta dauden entitateen sare erraldoi gisa ikus daiteke.

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 dokumentatuta. Datu-base grafiko bat abiarazi dezakezu klik gutxi batzuetan. Hala ere, konfigurazio zehatzagoari dagokionez, beharrezko informazioa aurkitzea zaila. Horregatik, konfigurazio-parametro bat adierazi nahi dugu.

Amazon Neptuneren lehen inpresioak
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 "Load Balancing" gaiari buruzko doako web-mintegia.


Iturria: www.habr.com

Gehitu iruzkin berria