Pirmie iespaidi par Amazon Neptune

Sveiciens, Habrovskas iedzīvotāji. Gaidot kursu sākumu "AWS izstrādātājiem" Esam sagatavojuŔi interesanta materiāla tulkojumu.

Pirmie iespaidi par Amazon Neptune

Daudzos lietoÅ”anas gadÄ«jumos, kas mums patÄ«k bakdataKā mēs redzam mÅ«su klientu tÄ«mekļa vietnēs, atbilstoŔā informācija ir paslēpta savienojumos starp entÄ«tijām, piemēram, analizējot attiecÄ«bas starp lietotājiem, atkarÄ«bas starp elementiem vai savienojumus starp sensoriem. Šādi lietoÅ”anas gadÄ«jumi parasti tiek modelēti pēc grafika. Å Ä« gada sākumā Amazon izlaida savu jauno grafiku datu bāzi Neptune. Å ajā ierakstā mēs vēlamies dalÄ«ties ar savām pirmajām idejām, labo praksi un to, ko laika gaitā var uzlabot.

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. MusicBrainz apkopo visus iespējamos mÅ«zikas metadatus, piemēram, informāciju par māksliniekiem, dziesmām, albumu izlaidumiem vai koncertiem, kā arÄ« to, ar ko sadarbojies dziesmas izpildÄ«tājs vai kad kurā valstÄ« albums tika izdots. MusicBrainz var uzskatÄ«t par milzÄ«gu vienÄ«bu tÄ«klu, kas kaut kādā veidā ir saistÄ«ti ar mÅ«zikas industriju.

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 dokumentēts. Varat palaist diagrammu datu bāzi tikai ar dažiem klikŔķiem. Tomēr, runājot par detalizētāku konfigurāciju, nepiecieÅ”amo informāciju grÅ«ti atrast. Tāpēc mēs vēlamies norādÄ«t uz vienu konfigurācijas parametru.

Pirmie iespaidi par Amazon Neptune
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 bezmaksas vebinārs par tēmu ā€œSlodzes lÄ«dzsvaroÅ”anaā€.


Avots: www.habr.com

Pievieno komentāru