Përshtypjet e para të Neptunit të Amazonës

Përshëndetje, banorë të Khabrovsk. Në pritje të fillimit të kursit "AWS për Zhvilluesit" Ne kemi përgatitur një përkthim të materialit interesant.

Përshtypjet e para të Neptunit të Amazonës

Në shumë raste përdorime që na pëlqejnë bakdataSiç e shohim në faqet e internetit të klientëve tanë, informacioni përkatës fshihet në lidhjet midis subjekteve, për shembull kur analizohen marrëdhëniet midis përdoruesve, varësitë midis elementeve ose lidhjet midis sensorëve. Raste të tilla përdorimi zakonisht modelohen në një grafik. Në fillim të këtij viti, Amazon publikoi bazën e të dhënave të re të grafikëve, Neptun. Në këtë postim ne duam të ndajmë idetë tona të para, praktikat e mira dhe çfarë mund të përmirësohet me kalimin e kohës.

Pse na duhej Amazon Neptuni

Bazat e të dhënave grafike premtojnë të trajtojnë grupe të dhënash shumë të lidhura më mirë sesa ekuivalentët e tyre relacionalë. Në grupe të dhënash të tilla, informacioni përkatës zakonisht ruhet në marrëdhëniet midis objekteve. Ne përdorëm një projekt të mahnitshëm të të dhënave të hapura për të testuar Neptunin MusicBrainz. MusicBrainz mbledh çdo lloj të meta të dhënave muzikore që mund të imagjinohet, të tilla si informacione rreth artistëve, këngëve, publikimeve të albumeve ose koncerteve, si dhe me kë bashkëpunoi artisti pas këngës ose kur albumi u publikua në cilin vend. MusicBrainz mund të shihet si një rrjet i madh entitetesh që janë disi të lidhura me industrinë e muzikës.

Të dhënat e MusicBrainz ofrohen si një depo CSV e një baze të dhënash relacionale. Në total, deponia përmban rreth 93 milionë rreshta në 157 tabela. Ndërsa disa nga këto tabela përmbajnë të dhëna bazë si artistë, ngjarje, regjistrime, publikime ose këngë, të tjera tabelat e lidhjeve — ruani marrëdhëniet ndërmjet artistëve dhe regjistrimeve, artistëve të tjerë ose publikimeve, etj... Ato demonstrojnë strukturën e grafikut të një grupi të dhënash. Kur konvertuam grupin e të dhënave në treshe RDF, morëm afërsisht 500 milionë raste.

Bazuar në përvojën dhe përshtypjet e partnerëve të projektit me të cilët punojmë, ne paraqesim një mjedis në të cilin kjo bazë njohurish përdoret për të marrë informacion të ri. Përveç kësaj, ne presim që ai të përditësohet rregullisht, për shembull duke shtuar botime të reja ose duke përditësuar anëtarët e grupit.

rregullim

Siç pritej, instalimi i Amazon Neptune është i thjeshtë. Ajo është mjaft e detajuar të dokumentuara. Ju mund të nisni një bazë të dhënash grafiku në vetëm disa klikime. Megjithatë, kur bëhet fjalë për konfigurim më të detajuar, informacionin e nevojshëm vështirë për t'u gjetur. Prandaj, ne duam të tregojmë një parametër të konfigurimit.

Përshtypjet e para të Neptunit të Amazonës
Pamja e ekranit të konfigurimit për grupet e parametrave

Amazon thotë se Neptuni fokusohet në ngarkesat e punës transaksionale me vonesë të ulët, kjo është arsyeja pse koha e paracaktuar e kërkesës është 120 sekonda. Megjithatë, ne kemi testuar shumë raste të përdorimit analitik në të cilat kemi arritur rregullisht këtë kufi. Ky afat kohor mund të ndryshohet duke krijuar një grup të ri parametrash për Neptunin dhe vendosjen neptune_query_timeout kufizimi përkatës.

Ngarkimi i të dhënave

Më poshtë do të diskutojmë në detaje se si i ngarkuam të dhënat e MusicBrainz në Neptun.

Marrëdhëniet në treshe

Së pari, ne i konvertuam të dhënat e MusicBrainz në treshe RDF. Prandaj, për secilën tabelë, ne përcaktuam një shabllon që përcakton se si çdo kolonë përfaqësohet në treshe. Në këtë shembull, çdo rresht nga tabela e interpretuesit është hartuar në dymbëdhjetë treshe 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> .

Ngarkimi në masë

Mënyra e sugjeruar për të ngarkuar sasi të mëdha të dhënash në Neptun është përmes procesit të ngarkimit me shumicë përmes S3. Pasi të keni ngarkuar skedarët tuaj të trefishtë në S3, ju filloni ngarkimin duke përdorur një kërkesë POST. Në rastin tonë, u deshën rreth 24 orë për 500 milionë trenjakë. Ne prisnim që të ishte më i shpejtë.

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

Për të shmangur këtë proces të gjatë sa herë që lëshojmë Neptunin, vendosëm të rivendosim shembullin nga një fotografi në të cilën këto treshe ishin të ngarkuara tashmë. Ekzekutimi nga një fotografi është dukshëm më i shpejtë, por ende zgjat rreth një orë derisa Neptuni të jetë i disponueshëm për kërkesa.

Kur ngarkuam fillimisht trenjakët në Neptun, hasëm gabime të ndryshme.

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

Disa prej tyre ishin gabime analizimi, siç tregohet më sipër. Deri më sot, ne ende nuk e kemi kuptuar se çfarë saktësisht shkoi keq në këtë pikë. Pak më shumë detaje do të ndihmonin patjetër këtu. Ky gabim ndodhi për rreth 1% të trefishave të futura. Por për sa i përket testimit të Neptunit, ne pranuam faktin që ne punojmë vetëm me 99% të informacionit nga MusicBrainz.

Edhe pse kjo është e lehtë për njerëzit e njohur me SPARQL, kini parasysh se trefishat RDF duhet të shënohen me lloje të qarta të dhënash, të cilat përsëri mund të shkaktojnë gabime.

Shkarkimi në transmetim

Siç u përmend më lart, ne nuk duam ta përdorim Neptunin si një ruajtje statike të të dhënave, por më tepër si një bazë njohurish fleksibël dhe në zhvillim. Pra, na duhej të gjenim mënyra për të prezantuar treshe të reja kur ndryshon baza e njohurive, për shembull kur publikohet një album i ri ose kur duam të materializojmë njohuritë e përftuara.

Neptuni mbështet operatorët e hyrjes përmes pyetjeve SPARQL, si të papërpunuara ashtu edhe të bazuara në mostra. Ne do të diskutojmë të dyja qasjet më poshtë.

Një nga qëllimet tona ishte futja e të dhënave në një mënyrë transmetimi. Merrni parasysh publikimin e një albumi në një vend të ri. Nga këndvështrimi i MusicBrainz, kjo do të thotë që për një publikim që përfshin albume, single, EP, etj., një hyrje e re shtohet në tabelë. lirim-vend. Në RDF, ne përputhim këtë informacion me dy treshe të reja.

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

Një qëllim tjetër ishte marrja e njohurive të reja nga grafiku. Le të themi se duam të marrim numrin e publikimeve që secili artist ka publikuar në karrierën e tij. Një pyetje e tillë është mjaft komplekse dhe zgjat mbi 20 minuta në Neptun, kështu që ne duhet të materializojmë rezultatin në mënyrë që të ripërdorim këtë njohuri të re në ndonjë pyetje tjetër. Pra, ne shtojmë trefish me këtë informacion përsëri në grafik, duke futur rezultatin e nënpyetjes.

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
 
}

Shtimi i trefishave të vetme në grafik kërkon disa milisekonda, ndërsa koha e ekzekutimit për futjen e rezultatit të një nënpyetje varet nga koha e ekzekutimit të vetë nënpyetjes.

Edhe pse nuk e kemi përdorur shpesh, Neptuni ju lejon gjithashtu të hiqni trenjakët bazuar në mostra ose të dhëna të qarta, të cilat mund të përdoren për të përditësuar informacionin.

Pyetjet SPARQL

Duke prezantuar nënkampionin e mëparshëm, i cili kthen numrin e publikimeve për çdo artist, ne kemi prezantuar tashmë llojin e parë të pyetjes që duam t'i përgjigjemi duke përdorur Neptun. Ndërtimi i një pyetjeje në Neptun është i lehtë - dërgoni një kërkesë POST në pikën përfundimtare SPARQL, siç tregohet më poshtë:

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

Për më tepër, ne kemi zbatuar një pyetje që kthen një profil artisti që përmban informacione për emrin, moshën ose vendin e origjinës së tyre. Mbani në mend se interpretuesit mund të jenë individë, grupe ose orkestra. Përveç kësaj, ne i plotësojmë këto të dhëna me informacione për numrin e publikimeve të lëshuara nga artistët gjatë vitit. Për artistët solo, ne gjithashtu shtojmë informacione për grupet në të cilat artisti mori pjesë çdo vit.

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

Për shkak të kompleksitetit të një pyetjeje të tillë, ne mund të kryenim pyetje pikash vetëm për një artist specifik, siç është Elton John, por jo për të gjithë artistët. Neptuni nuk duket se e optimizon një pyetje të tillë duke hedhur filtra në nën-zgjedhjet. Prandaj, çdo përzgjedhje duhet të filtrohet manualisht sipas emrit të artistit.

Neptuni ka tarifa për orë dhe për I/O. Për testimin tonë, ne përdorëm shembullin minimal të Neptunit, i cili kushton 0,384 dollarë/orë. Në rastin e pyetjes së mësipërme, e cila llogarit profilin për një punonjës të vetëm, Amazon na ngarkon me dhjetëra mijëra operacione I/O, duke nënkuptuar një kosto prej 0.02 dollarë.

Prodhim

Së pari, Amazon Neptuni mban shumicën e premtimeve të tij. Si një shërbim i menaxhuar, është një bazë të dhënash grafike që instalohet jashtëzakonisht lehtë dhe mund të funksionojë pa shumë konfigurime. Këtu janë pesë gjetjet tona kryesore:

  • Ngarkimi në masë është i lehtë, por i ngadalshëm. Por mund të ndërlikohet me mesazhe gabimi që nuk janë shumë të dobishme.
  • Shkarkimi i transmetimit mbështet gjithçka që prisnim dhe ishte mjaft i shpejtë
  • Pyetjet janë të thjeshta, por jo mjaftueshëm interaktive për të ekzekutuar pyetje analitike
  • Pyetjet SPARQL duhet të optimizohen manualisht
  • Pagesat e Amazon janë të vështira për t'u vlerësuar sepse është e vështirë të vlerësohet sasia e të dhënave të skanuara nga një pyetje SPARQL.

Kjo eshte e gjitha. Rregjistrohu Per Webinar falas me temën "Balancimi i ngarkesës".


Burimi: www.habr.com

Shto një koment