Maonyesho ya kwanza ya Amazon Neptune

Salamu, wakazi wa Khabrovsk. Kwa kutarajia kuanza kwa kozi "AWS kwa Wasanidi Programu" Tumetayarisha tafsiri ya nyenzo za kuvutia.

Maonyesho ya kwanza ya Amazon Neptune

Katika hali nyingi za utumiaji ambazo tunapenda bakdataKama tunavyoona kwenye tovuti za wateja wetu, maelezo muhimu hufichwa katika miunganisho kati ya huluki, kwa mfano wakati wa kuchanganua uhusiano kati ya watumiaji, utegemezi kati ya vipengele, au miunganisho kati ya vitambuzi. Kesi kama hizo za utumiaji kawaida huwekwa kwenye grafu. Mapema mwaka huu, Amazon ilitoa hifadhidata yake mpya ya grafu, Neptune. Katika chapisho hili tunataka kushiriki maoni yetu ya kwanza, mazoea mazuri na kile kinachoweza kuboreshwa kwa wakati.

Kwa nini tulihitaji Amazon Neptune

Hifadhidata za grafu huahidi kushughulikia seti za data zilizounganishwa sana kuliko sawa na uhusiano wao. Katika hifadhidata kama hizi, habari muhimu kawaida huhifadhiwa katika uhusiano kati ya vitu. Tulitumia mradi wa ajabu wa data wazi kujaribu Neptune MusicBrainz. MusicBrainz hukusanya kila aina ya metadata ya muziki inayoweza kufikiriwa, kama vile maelezo kuhusu wasanii, nyimbo, matoleo ya albamu au matamasha, na vile vile msanii wa wimbo alishirikiana naye au wakati albamu ilitolewa katika nchi gani. MusicBrainz inaweza kuonekana kama mtandao mkubwa wa vyombo ambavyo vimeunganishwa kwa tasnia ya muziki.

Seti ya data ya MusicBrainz imetolewa kama dampo la CSV la hifadhidata ya uhusiano. Kwa jumla, dampo lina takriban safu milioni 93 katika jedwali 157. Ingawa baadhi ya majedwali haya yana data ya msingi kama vile wasanii, matukio, rekodi, matoleo au nyimbo, nyinginezo meza za kiungo β€” kuhifadhi uhusiano kati ya wasanii na rekodi, wasanii wengine au matoleo, n.k... Huonyesha muundo wa grafu wa seti ya data. Wakati wa kubadilisha mkusanyiko wa data kuwa wa RDF mara tatu, tulipata takriban matukio milioni 500.

Kulingana na uzoefu na hisia za washirika wa mradi ambao tunafanya kazi nao, tunawasilisha mpangilio ambao msingi huu wa maarifa unatumiwa kupata taarifa mpya. Zaidi ya hayo, tunatarajia isasishwe mara kwa mara, kwa mfano kwa kuongeza matoleo mapya au kusasisha washiriki wa kikundi.

marekebisho

Kama inavyotarajiwa, kusakinisha Amazon Neptune ni rahisi. Yeye ni kina kabisa kumbukumbu. Unaweza kuzindua hifadhidata ya grafu kwa kubofya mara chache tu. Walakini, inapokuja kwa usanidi wa kina zaidi, taarifa muhimu vigumu kupata. Kwa hiyo, tunataka kutaja parameter moja ya usanidi.

Maonyesho ya kwanza ya Amazon Neptune
Picha ya skrini ya usanidi kwa vikundi vya vigezo

Amazon inasema Neptune inaangazia upakiaji wa shughuli za muda wa chini, ndiyo maana muda wa ombi chaguo-msingi ni sekunde 120. Hata hivyo, tumejaribu visa vingi vya utumiaji vya uchanganuzi ambapo tulifikia kikomo hiki mara kwa mara. Muda huu wa kuisha unaweza kubadilishwa kwa kuunda kikundi kipya cha vigezo vya Neptune na mipangilio neptune_query_timeout kizuizi kinacholingana.

Inapakia Data

Hapo chini tutajadili kwa kina jinsi tulivyopakia data ya MusicBrainz kwenye Neptune.

Mahusiano katika watatu

Kwanza, tulibadilisha data ya MusicBrainz kuwa mara tatu ya RDF. Kwa hiyo, kwa kila meza, tulifafanua template ambayo inafafanua jinsi kila safu inawakilishwa katika tatu. Katika mfano huu, kila safu kutoka kwa jedwali la uigizaji imechorwa hadi mara tatu ya RDF.

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

upakiaji wa wingi

Njia inayopendekezwa ya kupakia kiasi kikubwa cha data kwenye Neptune ni kupitia mchakato wa upakiaji wa wingi kupitia S3. Baada ya kupakia faili zako mara tatu kwa S3, unaanza kupakia kwa kutumia ombi la POST. Kwa upande wetu, ilichukua kama masaa 24 kwa mapacha milioni 500. Tulitarajia itakuwa haraka zaidi.

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

Ili kuepuka mchakato huu mrefu kila tunapozindua Neptune, tuliamua kurejesha mfano kutoka kwa muhtasari ambao sehemu tatu hizi tayari zilikuwa zimepakiwa. Kukimbia kutoka kwa muhtasari ni haraka sana, lakini bado huchukua kama saa moja hadi Neptune ipatikane kwa maombi.

Wakati wa kupakia mapacha watatu kwenye Neptune, tulikumbana na hitilafu mbalimbali.

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

Baadhi yao walikuwa na makosa ya kuchanganua, kama inavyoonyeshwa hapo juu. Hadi sasa, bado hatujafahamu ni nini hasa kilienda vibaya wakati huu. Maelezo kidogo zaidi yangesaidia hapa. Hitilafu hii ilitokea kwa takriban 1% ya mara tatu zilizoingizwa. Lakini kuhusu kujaribu Neptune, tulikubali ukweli kwamba tunafanya kazi tu na 99% ya maelezo kutoka MusicBrainz.

Ingawa hii ni rahisi kwa watu wanaoifahamu SPARQL, fahamu kwamba RDF mara tatu lazima ifafanuliwe na aina za data dhahiri, ambazo zinaweza kusababisha makosa tena.

Upakuaji wa kutiririsha

Kama ilivyotajwa hapo juu, hatutaki kutumia Neptune kama hifadhi tuli ya data, lakini kama msingi wa maarifa unaobadilika na unaobadilika. Kwa hivyo tulihitaji kutafuta njia za kutambulisha mara tatu mpya msingi wa maarifa unapobadilika, kwa mfano wakati albamu mpya inapochapishwa au tunapotaka kupata maarifa yaliyotolewa.

Neptune inasaidia waendeshaji ingizo kupitia hoja za SPARQL, ghafi na kulingana na sampuli. Tutajadili mbinu zote mbili hapa chini.

Moja ya malengo yetu ilikuwa kuingiza data kwa njia ya utiririshaji. Fikiria kutoa albamu katika nchi mpya. Kwa mtazamo wa MusicBrainz, hii inamaanisha kuwa kwa toleo linalojumuisha albamu, single, EP, n.k., ingizo jipya linaongezwa kwenye jedwali. nchi ya kutolewa. Katika RDF, tunalinganisha maelezo haya na mara tatu mpya.

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

Lengo lingine lilikuwa kupata maarifa mapya kutoka kwa grafu. Wacha tuseme tunataka kupata idadi ya matoleo ambayo kila msanii amechapisha katika taaluma yake. Hoja kama hii ni ngumu sana na huchukua zaidi ya dakika 20 huko Neptune, kwa hivyo tunahitaji kutekeleza matokeo ili kutumia tena maarifa haya mapya katika hoja nyingine. Kwa hivyo tunaongeza mara tatu na habari hii nyuma kwenye grafu, tukiingiza matokeo ya subquery.

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
 
}

Kuongeza mara tatu kwenye grafu huchukua milisekunde chache, huku muda wa utekelezaji wa kuingiza matokeo ya hoja ndogo unategemea muda wa utekelezaji wa hoja yenyewe.

Ingawa hatukuitumia mara kwa mara, Neptune pia hukuruhusu kuondoa sehemu tatu kulingana na sampuli au data dhahiri, ambayo inaweza kutumika kusasisha maelezo.

Maswali ya SPARQL

Kwa kutambulisha sampuli ya awali, ambayo inarejesha idadi ya matoleo kwa kila msanii, tayari tumeanzisha aina ya kwanza ya swali tunalotaka kujibu kwa kutumia Neptune. Kuunda swali katika Neptune ni rahisi - tuma ombi la POST kwa sehemu ya mwisho ya SPARQL, kama inavyoonyeshwa hapa chini:

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

Zaidi ya hayo, tumetekeleza swali ambalo hurejesha wasifu wa msanii ulio na maelezo kuhusu jina, umri au nchi yake ya asili. Kumbuka kwamba wasanii wanaweza kuwa watu binafsi, bendi, au orchestra. Zaidi ya hayo, tunaongeza data hii kwa maelezo kuhusu idadi ya matoleo yaliyotolewa na wasanii katika mwaka huo. Kwa wasanii wa pekee, pia tunaongeza maelezo kuhusu bendi ambazo msanii alishiriki kila mwaka.

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

Kwa sababu ya utata wa hoja kama hiyo, tunaweza tu kuuliza maswali ya uhakika kwa msanii mahususi, kama vile Elton John, lakini si kwa wasanii wote. Neptune haionekani kuboresha hoja kama hiyo kwa kudondosha vichujio kwenye vichaguo vidogo. Kwa hivyo, kila uteuzi lazima uchujwe mwenyewe kwa jina la msanii.

Neptune ina malipo ya kila saa na kwa-I/O. Kwa majaribio yetu, tulitumia mfano wa chini kabisa wa Neptune, ambao hugharimu $0,384/saa. Kwa upande wa hoja iliyo hapo juu, inayokokotoa wasifu kwa mfanyakazi mmoja, Amazon inatutoza makumi ya maelfu ya shughuli za I/O, ikimaanisha gharama ya $0.02.

Pato

Kwanza, Amazon Neptune hutimiza ahadi zake nyingi. Kama huduma inayosimamiwa, ni hifadhidata ya grafu ambayo ni rahisi sana kusakinisha na inaweza kuwa juu na kufanya kazi bila usanidi mwingi. Hapa kuna matokeo yetu makuu matano:

  • Kupakia kwa wingi ni rahisi lakini polepole. Lakini inaweza kuwa ngumu na ujumbe wa makosa ambayo sio muhimu sana.
  • Upakuaji wa kutiririsha unaauni kila kitu tulichotarajia na ulikuwa wa haraka sana
  • Hoja ni rahisi, lakini haziingiliani vya kutosha kuendesha maswali ya uchanganuzi
  • Hoja za SPARQL lazima ziboreshwe wewe mwenyewe
  • Malipo ya Amazon ni vigumu kukadiria kwa sababu ni vigumu kukadiria kiasi cha data iliyochanganuliwa na swali la SPARQL.

Ni hayo tu. Jisajili kwa wavuti ya bure kwenye mada "Kusawazisha Mzigo".


Chanzo: mapenzi.com

Kuongeza maoni