Prvi dojmovi Amazon Neptuna

Pozdrav, stanovnici Khabrovsk. U iščekivanju početka tečaja "AWS za programere" pripremio prijevod zanimljivog materijala.

Prvi dojmovi Amazon Neptuna

U mnogim slučajevima upotrebe koji nam se sviđaju bakdataKao što vidimo na web stranicama naših klijenata, relevantne informacije skrivene su u vezama između entiteta, na primjer kada se analiziraju odnosi između korisnika, ovisnosti između elemenata ili veze između senzora. Takvi slučajevi upotrebe obično se modeliraju na grafikonu. Ranije ove godine, Amazon je objavio svoju novu bazu podataka grafikona, Neptun. U ovom postu želimo podijeliti naše prve ideje, dobre prakse i ono što se s vremenom može poboljšati.

Zašto nam je trebao Amazon Neptun

Graf baze podataka obećavaju da će rukovati visoko povezanim skupovima podataka bolje od svojih relacijskih ekvivalenata. U takvim se skupovima podataka relevantne informacije obično pohranjuju u odnosima između objekata. Za testiranje Neptuna koristili smo nevjerojatan projekt otvorenih podataka MusicBrainz. MusicBrainz prikuplja sve vrste glazbenih metapodataka koje možete zamisliti, kao što su informacije o izvođačima, pjesmama, izdanjima albuma ili koncertima, kao i s kim je izvođač surađivao iza pjesme ili kada je album objavljen u kojoj zemlji. MusicBrainz se može promatrati kao ogromna mreža entiteta koji su na neki način povezani s glazbenom industrijom.

Skup podataka MusicBrainz dostupan je kao CSV ispis relacijske baze podataka. Ukupno, dump sadrži oko 93 milijuna redaka u 157 tablica. Dok neke od ovih tablica sadrže osnovne podatke kao što su izvođači, događaji, snimke, izdanja ili pjesme, druge tablice veza — pohranjuju odnose između izvođača i snimaka, drugih izvođača ili izdanja, itd... Oni pokazuju strukturu grafikona skupa podataka. Prilikom pretvaranja skupa podataka u RDF triple, dobili smo približno 500 milijuna instanci.

Na temelju iskustva i dojmova partnera na projektu s kojima surađujemo, predstavljamo okruženje u kojem se ta baza znanja koristi za dobivanje novih informacija. Osim toga, očekujemo da će se redovito ažurirati, na primjer dodavanjem novih izdanja ili ažuriranjem članova grupe.

podešavanje

Kao što se i očekivalo, instalacija Amazon Neptuna je jednostavna. Ona je dosta detaljna dokumentirano. Možete pokrenuti bazu podataka grafikona u samo nekoliko klikova. Međutim, kada je riječ o detaljnijoj konfiguraciji, potrebne informacije teško naći. Stoga želimo ukazati na jedan konfiguracijski parametar.

Prvi dojmovi Amazon Neptuna
Snimka zaslona konfiguracije za grupe parametara

Amazon kaže da se Neptune fokusira na transakcijska opterećenja niske latencije, zbog čega je zadano vremensko ograničenje zahtjeva 120 sekundi. Međutim, testirali smo mnoge analitičke slučajeve upotrebe u kojima smo redovito dostizali ovu granicu. Ovo vremensko ograničenje može se promijeniti stvaranjem nove grupe parametara za Neptune i postavljanjem neptune_query_timeout odgovarajuće ograničenje.

Učitavanje podataka

U nastavku ćemo detaljno raspravljati o tome kako smo učitali MusicBrainz podatke u Neptune.

Odnosi u troje

Prvo smo pretvorili MusicBrainz podatke u RDF trojke. Stoga smo za svaku tablicu definirali predložak koji definira kako je svaki stupac predstavljen u trojki. U ovom primjeru, svaki redak iz tablice izvođača preslikan je na dvanaest RDF trojki.

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

Skupni prijenos

Predloženi način za učitavanje velikih količina podataka u Neptune je proces skupnog učitavanja putem S3. Nakon učitavanja vaših trostrukih datoteka na S3, započinjete učitavanje pomoću POST zahtjeva. U našem slučaju, za 24 milijuna trojki bilo je potrebno oko 500 sata. Očekivali smo da će biti brže.

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

Kako bismo izbjegli ovaj dugotrajan proces svaki put kada pokrenemo Neptune, odlučili smo vratiti instancu iz snimke u kojoj su ove trojke već bile učitane. Pokretanje iz snimke znatno je brže, ali i dalje traje oko sat vremena dok Neptune ne postane dostupan za zahtjeve.

Prilikom početnog učitavanja trojki u Neptune, naišli smo na razne pogreške.

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

Neke od njih bile su pogreške u raščlanjivanju, kao što je gore prikazano. Do danas još uvijek nismo shvatili što je točno pošlo po zlu u ovom trenutku. Ovdje bi svakako pomoglo malo više detalja. Ova se pogreška dogodila za približno 1% umetnutih trojki. Ali što se tiče testiranja Neptuna, prihvatili smo činjenicu da radimo samo s 99% informacija iz MusicBrainza.

Iako je ovo jednostavno za ljude koji poznaju SPARQL, imajte na umu da RDF trostruki moraju biti označeni eksplicitnim tipovima podataka, što opet može uzrokovati pogreške.

Streaming preuzimanje

Kao što je gore spomenuto, Neptun ne želimo koristiti kao statičnu pohranu podataka, već kao fleksibilnu bazu znanja koja se razvija. Stoga smo morali pronaći načine za uvođenje novih trojki kada se baza znanja promijeni, na primjer kada se objavi novi album ili kada želimo materijalizirati izvedeno znanje.

Neptune podržava operatore unosa kroz SPARQL upite, neobrađene i temeljene na uzorku. U nastavku ćemo razmotriti oba pristupa.

Jedan od naših ciljeva bio je unos podataka na streaming način. Razmislite o izdavanju albuma u novoj zemlji. Iz perspektive MusicBrainza, to znači da se za izdanje koje uključuje albume, singlove, EP-ove itd. u tablicu dodaje novi unos puštanje-zemlja. U RDF-u povezujemo ove informacije s dvije nove trojke.

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

Drugi cilj je bio dobiti nova znanja iz grafikona. Recimo da želimo dobiti broj izdanja koje je svaki umjetnik objavio u svojoj karijeri. Takav upit je prilično složen i traje više od 20 minuta u Neptunu, pa moramo materijalizirati rezultat kako bismo to novo znanje ponovno upotrijebili u nekom drugom upitu. Stoga dodajemo trojke s ovim informacijama natrag na grafikon, unoseći rezultat podupita.

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
 
}

Dodavanje pojedinačne trojke na graf traje nekoliko milisekundi, dok vrijeme izvršenja za umetanje rezultata podupita ovisi o vremenu izvršenja samog podupita.

Iako ga nismo često koristili, Neptune također omogućuje uklanjanje trojki na temelju uzoraka ili eksplicitnih podataka, koji se mogu koristiti za ažuriranje informacija.

SPARQL upiti

Uvođenjem prethodnog poduzorka, koji vraća broj izdanja za svakog izvođača, već smo uveli prvu vrstu upita na koji želimo odgovoriti pomoću Neptuna. Izrada upita u Neptuneu je jednostavna - pošaljite POST zahtjev SPARQL krajnjoj točki, kao što je prikazano u nastavku:

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

Osim toga, implementirali smo upit koji vraća profil umjetnika koji sadrži informacije o njihovom imenu, dobi ili zemlji podrijetla. Imajte na umu da izvođači mogu biti pojedinci, bendovi ili orkestri. Osim toga, ove podatke dopunjujemo informacijama o broju izdanja koje su izvođači objavili tijekom godine. Za solo izvođače također dodajemo informacije o bendovima u kojima je taj izvođač sudjelovao svake godine.

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

Zbog složenosti takvog upita, mogli smo izvršiti upite samo za određenog izvođača, kao što je Elton John, ali ne za sve izvođače. Čini se da Neptune ne optimizira takav upit ispuštanjem filtara u pododabrane. Stoga se svaki odabir mora ručno filtrirati prema imenu izvođača.

Neptune ima naknade po satu i po I/O. Za naše testiranje koristili smo minimalnu instancu Neptune, koja košta 0,384 USD/sat. U slučaju gornjeg upita, koji izračunava profil za jednog radnika, Amazon nam naplaćuje desetke tisuća I/O operacija, što implicira trošak od 0.02 USD.

Izlaz

Prvo, Amazon Neptune održava većinu svojih obećanja. Kao upravljana usluga, to je grafička baza podataka koja se iznimno lako instalira i može se pokrenuti bez puno konfiguracije. Evo naših pet ključnih nalaza:

  • Skupni prijenos je jednostavan, ali spor. Ali može se zakomplicirati s porukama o pogreškama koje nisu od velike pomoći.
  • Streaming preuzimanje podržava sve što smo očekivali i bilo je prilično brzo
  • Upiti su jednostavni, ali nedovoljno interaktivni za pokretanje analitičkih upita
  • SPARQL upiti moraju se optimizirati ručno
  • Amazon plaćanja teško je procijeniti jer je teško procijeniti količinu podataka skeniranih SPARQL upitom.

To je sve. Prijaviti se za besplatni webinar na temu “Balansiranje opterećenja”.


Izvor: www.habr.com

Dodajte komentar