Pirmieji įspūdžiai apie Amazon Neptūną

Sveikinimai, chabrovskiečiai. Belaukiant kursų pradžios „AWS kūrėjams“ Parengėme įdomios medžiagos vertimą.

Pirmieji įspūdžiai apie Amazon Neptūną

Daugeliu mums patinkančių naudojimo atvejų bakdataKaip matome mūsų klientų svetainėse, aktuali informacija yra paslėpta ryšiuose tarp objektų, pavyzdžiui, analizuojant vartotojų santykius, elementų priklausomybes ar jutiklių ryšius. Tokie naudojimo atvejai dažniausiai modeliuojami pagal grafiką. Šių metų pradžioje „Amazon“ išleido savo naują grafikų duomenų bazę „Neptune“. Šiame įraše norime pasidalinti savo pirmosiomis idėjomis, gerąja praktika ir tuo, ką laikui bėgant galima patobulinti.

Kodėl mums reikėjo „Amazon Neptūno“.

Grafų duomenų bazės žada geriau tvarkyti labai sujungtus duomenų rinkinius nei jų reliaciniai ekvivalentai. Tokiuose duomenų rinkiniuose atitinkama informacija paprastai saugoma objektų santykiuose. Neptūnui išbandyti naudojome nuostabų atvirų duomenų projektą „MusicBrainz“. MusicBrainz renka visus įmanomus muzikos metaduomenis, pvz., informaciją apie atlikėjus, dainas, albumų leidimus ar koncertus, taip pat su kuo bendradarbiavo dainos atlikėjas arba kada kurioje šalyje albumas buvo išleistas. „MusicBrainz“ gali būti vertinamas kaip didžiulis subjektų, kažkaip susijusių su muzikos industrija, tinklas.

„MusicBrainz“ duomenų rinkinys pateikiamas kaip reliacinės duomenų bazės CSV išrašas. Iš viso sąvartynoje yra apie 93 milijonai eilučių 157 lentelėse. Nors kai kuriose iš šių lentelių yra pagrindiniai duomenys, pvz., atlikėjai, įvykiai, įrašai, leidimai ar takeliai ir kiti nuorodų lentelės — saugoti ryšius tarp atlikėjų ir įrašų, kitų atlikėjų ar leidimų ir tt... Jie parodo duomenų rinkinio grafinę struktūrą. Konvertuodami duomenų rinkinį į RDF trigubus, gavome maždaug 500 milijonų atvejų.

Remdamiesi projekto partnerių, su kuriais dirbame, patirtimi ir įspūdžiais, pristatome aplinką, kurioje ši žinių bazė naudojama naujos informacijos gavimui. Be to, tikimės, kad jis bus reguliariai atnaujinamas, pavyzdžiui, įtraukiant naujus leidimus arba atnaujinant grupės narius.

reguliavimas

Kaip ir tikėtasi, įdiegti „Amazon Neptune“ yra paprasta. Ji gana detali dokumentuota. Galite paleisti diagramų duomenų bazę vos keliais paspaudimais. Tačiau kai kalbama apie detalesnę konfigūraciją, reikalinga informacija sunku rasti. Todėl norime nurodyti vieną konfigūracijos parametrą.

Pirmieji įspūdžiai apie Amazon Neptūną
Parametrų grupių konfigūracijos ekrano kopija

„Amazon“ teigia, kad „Neptune“ daugiausia dėmesio skiria mažos delsos operacijų darbo krūviams, todėl numatytasis užklausos skirtasis laikas yra 120 sekundžių. Tačiau išbandėme daug analitinio naudojimo atvejų, kai reguliariai pasiekėme šią ribą. Šį skirtąjį laiką galima pakeisti sukuriant naują parametrų grupę Neptūnui ir nustatant neptune_query_timeout atitinkamas apribojimas.

Įkeliami duomenys

Žemiau mes išsamiai aptarsime, kaip įkėlėme „MusicBrainz“ duomenis į „Neptune“.

Santykiai trise

Pirmiausia „MusicBrainz“ duomenis konvertavome į RDF trigubus. Todėl kiekvienai lentelei apibrėžėme šabloną, kuris apibrėžia, kaip kiekvienas stulpelis vaizduojamas triguboje. Šiame pavyzdyje kiekviena atlikėjų lentelės eilutė susieta su dvylika RDF trigubų.

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

masinis įkėlimas

Siūlomas būdas įkelti didelius duomenų kiekius į „Neptūną“ yra masinio įkėlimo procesas naudojant S3. Įkėlę trigubus failus į S3, pradėsite įkelti naudodami POST užklausą. Mūsų atveju 24 milijonų trynukų užtruko apie 500 valandas. Tikėjomės, kad bus greičiau.

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

Kad išvengtume šio ilgo proceso kiekvieną kartą, kai paleidžiame „Neptūną“, nusprendėme atkurti egzempliorių iš momentinės nuotraukos, kurioje šie trynukai jau buvo įkelti. Paleisti iš momentinės nuotraukos yra žymiai greičiau, bet vis tiek užtrunka maždaug valandą, kol „Neptūnas“ bus pasiekiamas užklausoms.

Iš pradžių įkeldami tripletus į Neptūną, susidūrėme su įvairiomis klaidomis.

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

Kai kurios iš jų buvo analizavimo klaidos, kaip parodyta aukščiau. Iki šiol mes vis dar nesupratome, kas šiuo metu tiksliai nutiko. Čia tikrai padėtų šiek tiek išsamesnė informacija. Ši klaida įvyko maždaug 1 % įterptų trigubų. Tačiau, kalbant apie Neptūno testavimą, mes sutikome su tuo, kad dirbame tik su 99% informacijos iš MusicBrainz.

Nors tai lengva žmonėms, susipažinusiems su SPARQL, atminkite, kad RDF trigubos turi būti komentuojamos aiškiais duomenų tipais, o tai vėl gali sukelti klaidų.

Srautinės transliacijos atsisiuntimas

Kaip minėta pirmiau, mes nenorime naudoti „Neptūno“ kaip statinės duomenų saugyklos, o kaip lanksčią ir besikeičiančią žinių bazę. Taigi, pasikeitus žinių bazei, pavyzdžiui, kai išleidžiamas naujas albumas arba kai norime materializuoti gautas žinias, reikėjo rasti būdų, kaip įvesti naujus trigubus.

„Neptune“ palaiko įvesties operatorius per SPARQL užklausas, tiek neapdorotas, tiek imties pagrindu. Toliau aptarsime abu būdus.

Vienas iš mūsų tikslų buvo įvesti duomenis srautiniu būdu. Apsvarstykite galimybę išleisti albumą naujoje šalyje. „MusicBrainz“ požiūriu tai reiškia, kad leidimui, kuriame yra albumų, singlų, EP ir kt., į lentelę įtraukiamas naujas įrašas išleidimo šalis. RDF sistemoje šią informaciją suderiname su dviem naujais trigubais.

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

Kitas tikslas buvo gauti naujų žinių iš grafiko. Tarkime, kad norime gauti kiekvieno atlikėjo per savo karjerą paskelbtų leidimų skaičių. Tokia užklausa yra gana sudėtinga ir „Neptūne“ užtrunka daugiau nei 20 minučių, todėl turime realizuoti rezultatą, kad galėtume panaudoti šias naujas žinias kitoje užklausoje. Taigi mes įtraukiame trigubus su šia informacija atgal į grafiką, įvesdami antrinės užklausos rezultatą.

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
 
}

Pavienių trigubų įtraukimas į grafiką užtrunka keletą milisekundžių, o antrinės užklausos rezultato įterpimo vykdymo laikas priklauso nuo pačios antrinės užklausos vykdymo laiko.

Nors nenaudojome jo dažnai, „Neptūnas“ taip pat leidžia pašalinti tripletus pagal pavyzdžius arba aiškius duomenis, kuriuos galima naudoti informacijai atnaujinti.

SPARQL užklausos

Pristatydami ankstesnį pavyzdį, kuriame pateikiamas kiekvieno atlikėjo leidimų skaičius, mes jau pristatėme pirmojo tipo užklausą, į kurią norime atsakyti naudodami Neptūną. Sukurti užklausą „Neptune“ paprasta – nusiųskite POST užklausą į SPARQL galutinį tašką, kaip parodyta toliau:

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

Be to, įdiegėme užklausą, kuri pateikia atlikėjo profilį su informacija apie jo vardą, amžių arba kilmės šalį. Atminkite, kad atlikėjai gali būti asmenys, grupės ar orkestrai. Be to, šiuos duomenis papildome informacija apie atlikėjų išleistų leidimų skaičių per metus. Solo atlikėjams taip pat pridedame informaciją apie grupes, kuriose atlikėjas dalyvavo kiekvienais metais.

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

Dėl tokios užklausos sudėtingumo taškines užklausas galėjome atlikti tik konkrečiam atlikėjui, pvz., Eltonui Johnui, bet ne visiems atlikėjams. Panašu, kad „Neptūnas“ neoptimizuoja tokios užklausos, įmesdamas filtrus į pogrupius. Todėl kiekvienas pasirinkimas turi būti rankiniu būdu filtruojamas pagal atlikėjo vardą.

Neptūnas turi ir valandinius, ir per I/O įkrovimus. Testavimui naudojome minimalų „Neptūno“ egzempliorių, kuris kainuoja 0,384 USD per valandą. Aukščiau pateiktos užklausos, pagal kurią apskaičiuojamas vieno darbuotojo profilis, atveju „Amazon“ apmokestina dešimtis tūkstančių įvesties / išvesties operacijų, o tai reiškia 0.02 USD.

Produkcija

Pirma, „Amazon Neptune“ laikosi daugumos savo pažadų. Kaip valdoma paslauga, tai yra grafikų duomenų bazė, kurią labai lengva įdiegti ir kurią galima sukurti ir veikti be daug konfigūracijos. Štai penki pagrindiniai mūsų atradimai:

  • Masinis įkėlimas yra lengvas, bet lėtas. Tačiau tai gali būti sudėtinga dėl klaidų pranešimų, kurie nėra labai naudingi.
  • Srautinis atsisiuntimas palaiko viską, ko tikėjomės, ir buvo gana greitas
  • Užklausos yra paprastos, bet nepakankamai interaktyvios, kad būtų galima vykdyti analitines užklausas
  • SPARQL užklausos turi būti optimizuotos rankiniu būdu
  • „Amazon“ mokėjimus sunku įvertinti, nes sunku įvertinti duomenų, nuskaitytų naudojant SPARQL užklausą, kiekį.

Tai viskas. Užsiregistruoti nemokamas internetinis seminaras tema „Apkrovos balansavimas“.


Šaltinis: www.habr.com

Добавить комментарий