Unuaj impresoj de Amazon Neptune

Saluton, Ĥabrovskaj loĝantoj. Antaŭĝoje de la komenco de la kurso "AWS por Programistoj" Ni preparis tradukon de interesa materialo.

Unuaj impresoj de Amazon Neptune

En multaj uzaj kazoj, kiujn ni ŝatas bakdataKiel ni vidas en la retejoj de niaj klientoj, koncernaj informoj estas kaŝitaj en konektoj inter entoj, ekzemple kiam oni analizas rilatojn inter uzantoj, dependecojn inter elementoj aŭ konektojn inter sensiloj. Tiaj uzkazoj estas kutime modeligitaj sur grafeo. Komence de ĉi tiu jaro, Amazon publikigis sian novan grafikan datumbazon, Neptuno. En ĉi tiu afiŝo ni volas kunhavigi niajn unuajn ideojn, bonajn praktikojn kaj kio povas esti plibonigita kun la tempo.

Kial ni bezonis Amazon Neptune

Grafaj datumbazoj promesas pritrakti tre ligitajn datumarojn pli bone ol siaj interrilataj ekvivalentoj. En tiaj datenseroj, signifaj informoj estas kutime stokitaj en rilatoj inter objektoj. Ni uzis mirindan malferman datuman projekton por testi Neptunon MusicBrainz. MusicBrainz kolektas ĉiajn muzikmetadatumojn imageblajn, kiel informojn pri artistoj, kantoj, albumeldonoj aŭ koncertoj, kaj ankaŭ kun kiu kunlaboris la artisto malantaŭ la kanto aŭ kiam la albumo estis publikigita en kiu lando. MusicBrainz povas esti vidita kiel grandega reto de estaĵoj, kiuj estas iel konektitaj al la muzika industrio.

La MusicBrainz-datumaro estas disponigita kiel CSV-rubejo de interrilata datumbazo. Entute, la rubejo enhavas ĉirkaŭ 93 milionojn da vicoj en 157 tabeloj. Dum kelkaj el ĉi tiuj tabeloj enhavas bazajn datumojn kiel artistoj, eventoj, registradoj, eldonoj aŭ trakoj, aliaj ligi tabelojn — stoki rilatojn inter artistoj kaj registradoj, aliaj artistoj aŭ eldonoj, ktp... Ili montras la grafikan strukturon de datumaro. Konvertinte la datumaron en RDF-trioblojn, ni akiris proksimume 500 milionojn da okazoj.

Surbaze de la sperto kaj impresoj de la projektpartneroj kun kiuj ni laboras, ni prezentas agordon en kiu ĉi tiu scio bazo estas uzata por akiri novajn informojn. Krome, ni atendas ke ĝi estos regule ĝisdatigita, ekzemple aldonante novajn eldonojn aŭ ĝisdatigante grupanojn.

alĝustigo

Kiel atendite, instali Amazon Neptune estas simpla. Ŝi estas sufiĉe detala dokumentita. Vi povas lanĉi grafikan datumbazon per nur kelkaj klakoj. Tamen, se temas pri pli detala agordo, necesajn informojn malfacile trovebla. Tial ni volas montri unu agordan parametron.

Unuaj impresoj de Amazon Neptune
Agorda ekrankopio por parametrogrupoj

Amazon diras, ke Neptuno fokusiĝas al malalt-latentecaj transakciaj laborŝarĝoj, tial la defaŭlta peto-tempo estas 120 sekundoj. Ni tamen testis multajn analizajn uzkazojn, en kiuj ni regule atingis ĉi tiun limon. Ĉi tiu tempodaŭro povas esti ŝanĝita kreante novan parametran grupon por Neptuno kaj agordi neptune_query_timeout responda limigo.

Ŝarĝante Datumojn

Malsupre ni diskutos detale kiel ni ŝargis MusicBrainz-datumojn en Neptuno.

Rilatoj en triopo

Unue, ni konvertis la MusicBrainz-datumojn en RDF-trioblojn. Tial, por ĉiu tabelo, ni difinis ŝablonon kiu difinas kiel ĉiu kolumno estas reprezentita en la triopo. En ĉi tiu ekzemplo, ĉiu vico de la prezentisto-tabelo estas mapita al dek du RDF-triopoj.

<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> .

Poka alŝuto

La proponita maniero por ŝargi grandajn kvantojn da datumoj en Neptunon estas per la amasa alŝuta procezo per S3. Post alŝuto de viaj trioblaj dosieroj al S3, vi komencas la alŝuton uzante POST-peton. En nia kazo, daŭris ĉirkaŭ 24 horojn por 500 milionoj da trinasktioj. Ni atendis, ke ĝi estos pli rapida.

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"
 
}'

Por eviti ĉi tiun longan procezon ĉiufoje kiam ni lanĉas Neptunon, ni decidis restarigi la ekzemplon de momentfoto, en kiu ĉi tiuj trinasktioj jam estis ŝarĝitaj. Kurado de momentfoto estas signife pli rapida, sed ankoraŭ daŭras ĉirkaŭ unu horon ĝis Neptuno disponeblas por petoj.

Komence ŝarĝante trinasktiojn en Neptunon, ni renkontis diversajn erarojn.

{
 
 
 "errorCode" : "PARSING_ERROR",
 
 "errorMessage" : "Content after '.' is not allowed",
 
 "fileName" : [...],
 
 "recordNum" : 25
 
}

Kelkaj el ili estis analizaj eraroj, kiel montrite supre. Ĝis nun ni ankoraŭ ne eltrovis, kio precize misfunkciis ĉi-momente. Iom pli da detaloj certe helpus ĉi tie. Ĉi tiu eraro okazis por proksimume 1% de enmetitaj triobloj. Sed pri testado de Neptuno, ni akceptis la fakton, ke ni laboras nur kun 99% de la informoj de MusicBrainz.

Kvankam ĉi tio estas facila por homoj konataj kun SPARQL, konsciu, ke RDF-triopoj devas esti komentitaj per eksplicitaj datumtipoj, kiuj denove povas kaŭzi erarojn.

Streaming elŝuto

Kiel menciite supre, ni ne volas uzi Neptunon kiel senmovan datumbutikon, sed prefere kiel fleksebla kaj evoluanta sciobazo. Do ni bezonis trovi manierojn enkonduki novajn trioblojn kiam la sciobazo ŝanĝiĝas, ekzemple kiam nova albumo estas publikigita aŭ kiam ni volas materiigi derivitajn scion.

Neptuno subtenas enigfunkciigistojn per SPARQL-demandoj, ambaŭ krudaj kaj specimen-bazitaj. Ni diskutos ambaŭ alirojn sube.

Unu el niaj celoj estis enigi datumojn en fluanta maniero. Konsideru publikigi albumon en nova lando. El la perspektivo de MusicBrainz, tio signifas, ke por eldono kiu inkluzivas albumojn, unuopaĵojn, EP-ojn, ktp., nova eniro estas aldonita al la tabelo. liberigo-lando. En RDF, ni kongruas ĉi tiun informon kun du novaj triopoj.

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> };

Alia celo estis akiri novajn sciojn de la grafikaĵo. Ni diru, ke ni volas ricevi la nombron da eldonoj kiujn ĉiu artisto publikigis en sia kariero. Tia demando estas sufiĉe kompleksa kaj daŭras pli ol 20 minutojn en Neptuno, do ni devas materiigi la rezulton por reuzi ĉi tiun novan scion en iu alia demando. Do ni aldonas trioblojn kun ĉi tiu informo reen al la grafeo, enigante la rezulton de la subdemandado.

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
 
}

Aldonado de unuopaj triopoj al la grafeo prenas kelkajn milisekundojn, dum la ekzekuttempo por enmeti la rezulton de subdemando dependas de la ekzekuttempo de la subdemandado mem.

Kvankam ni ne ofte uzis ĝin, Neptuno ankaŭ ebligas al vi forigi trinasktiojn surbaze de specimenoj aŭ eksplicitaj datumoj, kiuj povas esti uzataj por ĝisdatigi informojn.

SPARQL-demandoj

Enkondukante la antaŭan subspecimenon, kiu redonas la nombron da eldonoj por ĉiu artisto, ni jam enkondukis la unuan tipon de demando, kiun ni volas respondi uzante Neptuno. Konstrui demandon en Neptuno estas facila - sendu POST-peton al la SPARQL-finpunkto, kiel montrite sube:

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

Aldone, ni efektivigis demandon, kiu resendas artistprofilon enhavantan informojn pri ilia nomo, aĝo aŭ devenlando. Memoru, ke la prezentistoj povas esti individuoj, grupoj aŭ orkestroj. Krome, ni kompletigas ĉi tiujn datumojn per informoj pri la nombro da eldonoj publikigitaj de artistoj dum la jaro. Por soloartistoj, ni ankaŭ aldonas informojn pri la grupoj, kiujn tiu artisto partoprenis ĉiun jaron.

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)
 
   }

Pro la komplekseco de tia demando, ni povus nur fari punktodemandojn por specifa artisto, kiel ekzemple Elton John, sed ne por ĉiuj artistoj. Neptuno ŝajnas ne optimumigi tian demandon faligante filtrilojn en subelektojn. Tial ĉiu elekto devas esti permane filtrita laŭ artistnomo.

Neptuno havas kaj horajn kaj po-I/O-kostojn. Por nia testado, ni uzis la minimuman ekzemplon de Neptuno, kiu kostas $ 0,384/horo. En la kazo de la ĉi-supra demando, kiu kalkulas la profilon por ununura laboristo, Amazon ŝargas al ni dekojn da miloj da I/O-operacioj, kio implicas koston de $0.02.

konkludo

Unue, Amazon Neptune plenumas la plej multajn el siaj promesoj. Kiel administrita servo, ĝi estas grafika datumbazo, kiu estas ege facile instalebla kaj povas funkcii sen multe da agordo. Jen niaj kvin ŝlosilaj trovoj:

  • Poka alŝuto estas facila sed malrapida. Sed ĝi povas kompliki kun erarmesaĝoj kiuj ne estas tre helpemaj.
  • Streaming elŝuto subtenas ĉion, kion ni atendis kaj estis sufiĉe rapida
  • Demandoj estas simplaj, sed ne sufiĉe interagaj por fari analizajn demandojn
  • SPARQL-demandoj devas esti optimumigitaj permane
  • Amazon-pagoj estas malfacile takseblaj ĉar estas malfacile taksi la kvanton da datumoj skanitaj per SPARQL-demando.

Tio estas ĉio. Aliĝu por senpaga retseminario pri la temo "Ŝarĝo-ekvilibro".


fonto: www.habr.com

Aldoni komenton