Fyrstu kynni af Amazon Neptune

Kveðja, íbúar Khabrovsk. Í tilefni af því að námskeiðið hefjist "AWS fyrir hönnuði" Við höfum útbúið þýðingu á áhugaverðu efni.

Fyrstu kynni af Amazon Neptune

Í mörgum tilfellum sem okkur líkar við bakgögnEins og við sjáum á vefsíðum viðskiptavina okkar eru viðeigandi upplýsingar falin í tengingum milli eininga, til dæmis þegar tengsl eru milli notenda, ósjálfstæði milli þátta eða tengingar milli skynjara eru greind. Slík notkunartilvik eru venjulega gerð á línuriti. Fyrr á þessu ári gaf Amazon út nýja línuritagagnagrunn sinn, Neptune. Í þessari færslu viljum við deila fyrstu hugmyndum okkar, góðum starfsháttum og því sem hægt er að bæta með tímanum.

Af hverju við þurftum Amazon Neptune

Línurit gagnagrunnar lofa að meðhöndla mjög tengd gagnasöfn betur en samsvörun þeirra. Í slíkum gagnasettum eru viðeigandi upplýsingar venjulega geymdar í tengslum milli hluta. Við notuðum ótrúlegt opið gagnaverkefni til að prófa Neptune TónlistBrainz. MusicBrainz safnar alls kyns lýsigögnum tónlistar sem hægt er að hugsa sér, svo sem upplýsingum um listamenn, lög, plötuútgáfur eða tónleika, sem og með hverjum listamaðurinn á bak við lagið var í samstarfi eða hvenær platan kom út í hvaða landi. Líta má á MusicBrainz sem risastórt net aðila sem á einhvern hátt tengjast tónlistariðnaðinum.

MusicBrainz gagnapakkinn er útvegaður sem CSV dump af venslagagnagrunni. Alls inniheldur sorphaugurinn um 93 milljónir raða í 157 töflum. Þó að sumar þessara taflna innihaldi grunngögn eins og listamenn, viðburði, upptökur, útgáfur eða lög, önnur tenglatöflur — geyma tengsl milli listamanna og upptökur, annarra listamanna eða útgáfur o.s.frv... Þau sýna fram á línuritsbyggingu gagnasafns. Þegar gagnagrunninum var breytt í RDF þrefalda fengum við um það bil 500 milljónir tilvika.

Byggt á reynslu og hughrifum samstarfsaðila verkefnisins sem við vinnum með, kynnum við umhverfi þar sem þessi þekkingargrunnur er notaður til að afla nýrra upplýsinga. Að auki gerum við ráð fyrir að það verði uppfært reglulega, til dæmis með því að bæta við nýjum útgáfum eða uppfæra hópmeðlimi.

aðlögun

Eins og búist var við er einföld uppsetning á Amazon Neptune. Hún er frekar ítarleg skjalfest. Þú getur ræst grafgagnagrunn með örfáum smellum. Hins vegar, þegar kemur að ítarlegri uppsetningu, nauðsynlegar upplýsingar erfitt að finna. Þess vegna viljum við benda á eina stillingarfæribreytu.

Fyrstu kynni af Amazon Neptune
Stillingarskjámynd fyrir færibreytuhópa

Amazon segir að Neptune einbeiti sér að viðskiptavinnuálagi með litla biðtíma og þess vegna er sjálfgefinn biðtími 120 sekúndur. Við höfum hins vegar prófað mörg greiningartilvik þar sem við náðum reglulega þessum mörkum. Þessum tímamörkum er hægt að breyta með því að búa til nýjan færibreytuhóp fyrir Neptúnus og stillingu neptune_query_timeout samsvarandi takmörkun.

Hleður gögnum

Hér að neðan munum við ræða í smáatriðum hvernig við hlóðum MusicBrainz gögnum inn í Neptune.

Sambönd í þrígang

Í fyrsta lagi breyttum við MusicBrainz gögnunum í RDF þrefalda. Þess vegna, fyrir hverja töflu, skilgreindum við sniðmát sem skilgreinir hvernig hver dálkur er táknaður í þrefaldinum. Í þessu dæmi er hver röð úr flytjandatöflunni varpað á tólf RDF þrefalda.

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

magnupphleðsla

Leiðbeinandi leiðin til að hlaða miklu magni af gögnum inn í Neptune er í gegnum magnupphleðsluferlið í gegnum S3. Eftir að hafa hlaðið upp þreföldum skrám þínum á S3 byrjar þú upphleðsluna með POST beiðni. Í okkar tilviki tók það um 24 klukkustundir fyrir 500 milljónir þríbura. Við áttum von á því að það yrði hraðari.

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

Til að forðast þetta langa ferli í hvert skipti sem við ræsum Neptune, ákváðum við að endurheimta tilvikið úr skyndimynd þar sem þessir þríburar voru þegar hlaðnir. Að keyra frá skyndimynd er verulega hraðari, en samt tekur um klukkutíma þar til Neptune er tiltækur fyrir beiðnir.

Við upphaflega að hlaða þríburum inn í Neptúnus, fundum við ýmsar villur.

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

Sumar þeirra voru þáttunarvillur, eins og sýnt er hér að ofan. Hingað til höfum við enn ekki fundið út hvað nákvæmlega fór úrskeiðis á þessum tímapunkti. Smá smáatriði myndu örugglega hjálpa hér. Þessi villa kom upp fyrir u.þ.b. 1% þrefalda sem settir voru inn. En hvað varðar prófanir á Neptune þá samþykktum við þá staðreynd að við vinnum aðeins með 99% af upplýsingum frá MusicBrainz.

Jafnvel þó að þetta sé auðvelt fyrir fólk sem þekkir SPARQL, vertu meðvitaður um að RDF þrefaldir verða að vera merktir með skýrum gagnategundum, sem aftur getur valdið villum.

Straum til að sækja

Eins og getið er hér að ofan viljum við ekki nota Neptúnus sem kyrrstæða gagnageymslu, heldur sem sveigjanlegan þekkingargrunn sem er í þróun. Við þurftum því að finna leiðir til að kynna nýja þrískiptingu þegar þekkingargrunnurinn breytist, til dæmis þegar ný plata kemur út eða þegar við viljum koma afleiddri þekkingu til skila.

Neptune styður inntaksstjóra í gegnum SPARQL fyrirspurnir, bæði hráar og sýnishornar. Við munum ræða báðar aðferðirnar hér að neðan.

Eitt af markmiðum okkar var að slá inn gögn í streymi. Íhugaðu að gefa út plötu í nýju landi. Frá sjónarhóli MusicBrainz þýðir þetta að fyrir útgáfu sem inniheldur plötur, smáskífur, EP, o.s.frv., er nýrri færsla bætt við töfluna sleppa-landi. Í RDF pörum við þessar upplýsingar með tveimur nýjum þreföldum.

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

Annað markmið var að fá nýja þekkingu úr línuritinu. Segjum að við viljum fá fjölda útgáfur sem hver listamaður hefur gefið út á ferlinum. Slík fyrirspurn er frekar flókin og tekur rúmar 20 mínútur í Neptúnusi, þannig að við þurfum að gera niðurstöðuna að veruleika til að endurnýta þessa nýju þekkingu í einhverri annarri fyrirspurn. Þannig að við bætum þreföldum með þessum upplýsingum aftur í línuritið, slærð inn niðurstöðu undirfyrirspurnarinnar.

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
 
}

Að bæta einum þreföldum við grafið tekur nokkrar millisekúndur, en framkvæmdartíminn til að setja inn niðurstöðu undirfyrirspurnar fer eftir framkvæmdartíma undirfyrirspurnarinnar sjálfrar.

Þó að við höfum ekki notað það oft, gerir Neptúnus þér einnig kleift að fjarlægja þríbura byggt á sýnum eða skýrum gögnum, sem hægt er að nota til að uppfæra upplýsingar.

SPARQL fyrirspurnir

Með því að kynna fyrra undirsýnishornið, sem skilar fjölda útgáfur fyrir hvern listamann, höfum við þegar kynnt fyrstu tegund fyrirspurnar sem við viljum svara með því að nota Neptune. Það er auðvelt að byggja upp fyrirspurn í Neptune - sendu POST beiðni til SPARQL endapunktsins, eins og sýnt er hér að neðan:

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

Að auki höfum við innleitt fyrirspurn sem skilar listamannsprófíl sem inniheldur upplýsingar um nafn þeirra, aldur eða upprunaland. Hafðu í huga að flytjendurnir geta verið einstaklingar, hljómsveitir eða hljómsveitir. Að auki bætum við þessi gögn með upplýsingum um fjölda útgáfur sem listamenn hafa gefið út á árinu. Fyrir sólólistamenn bætum við einnig við upplýsingum um þær hljómsveitir sem listamaðurinn tók þátt í á hverju ári.

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

Vegna þess hversu flókin slík fyrirspurn er, gátum við aðeins framkvæmt punktafyrirspurnir fyrir tiltekinn listamann, eins og Elton John, en ekki fyrir alla listamenn. Neptúnus virðist ekki hagræða slíkri fyrirspurn með því að sleppa síum í undirval. Þess vegna verður að sía hvert val handvirkt eftir nafni listamanns.

Neptúnus hefur bæði klukkutímahleðslu og per-I/O hleðslu. Við prófun okkar notuðum við lágmarks Neptune tilvik, sem kostar $ 0,384/klst. Þegar um er að ræða fyrirspurnina hér að ofan, sem reiknar út sniðið fyrir einn starfsmann, rukkar Amazon okkur um tugþúsundir inn/út aðgerða, sem þýðir kostnað upp á $0.02.

Output

Í fyrsta lagi stendur Amazon Neptune við flest loforð sín. Sem stýrð þjónusta er þetta grafgagnagrunnur sem er einstaklega auðvelt að setja upp og getur verið í gangi án mikillar stillingar. Hér eru fimm helstu niðurstöður okkar:

  • Fjöldiupphleðsla er auðveld en hægt. En það getur orðið flókið með villuboðum sem eru ekki mjög gagnlegar.
  • Straum niðurhal styður allt sem við áttum von á og var frekar hratt
  • Fyrirspurnir eru einfaldar en ekki nógu gagnvirkar til að keyra greiningarfyrirspurnir
  • SPARQL fyrirspurnir verða að fínstilla handvirkt
  • Erfitt er að áætla Amazon greiðslur vegna þess að erfitt er að áætla magn gagna sem skannað er með SPARQL fyrirspurn.

Það er allt og sumt. Skrá sig ókeypis vefnámskeið um efnið „álagsjöfnun“.


Heimild: www.habr.com

Bæta við athugasemd