Első benyomások az Amazon Neptune-ról

Üdvözlet Habrovszk lakosai. A tanfolyam kezdetére várva "AWS fejlesztőknek" Érdekes anyag fordítását készítettük el.

Első benyomások az Amazon Neptune-ról

Sok olyan felhasználási esetben, amit szeretünk bakdataAmint azt ügyfeleink weboldalain látjuk, a releváns információk az entitások közötti kapcsolatokban rejtőznek, például a felhasználók közötti kapcsolatok, az elemek közötti függőségek vagy az érzékelők közötti kapcsolatok elemzésekor. Az ilyen használati eseteket általában grafikonon modellezik. Az év elején az Amazon kiadta új gráfadatbázisát, a Neptune-t. Ebben a bejegyzésben szeretnénk megosztani első ötleteinket, jó gyakorlatainkat és azt, hogy mi az, ami idővel még javítható.

Miért volt szükségünk az Amazon Neptune-ra?

A gráf adatbázisok azt ígérik, hogy jobban kezelik a szorosan összekapcsolt adatkészleteket, mint relációs megfelelőik. Az ilyen adatkészletekben a releváns információkat általában az objektumok közötti kapcsolatokban tárolják. Egy csodálatos nyílt adatprojektet használtunk a Neptune tesztelésére MusicBrainz. A MusicBrainz minden elképzelhető zenei metaadatot összegyűjt, például információkat az előadókról, dalokról, albummegjelenítésekről vagy koncertekről, valamint arról, hogy a dal mögött álló előadó kivel működött együtt, vagy mikor, melyik országban jelent meg az album. A MusicBrainz olyan entitások hatalmas hálózatának tekinthető, amelyek valamilyen módon kapcsolódnak a zeneiparhoz.

A MusicBrainz adatkészlet egy relációs adatbázis CSV-kiíratásaként érhető el. Összességében a dump körülbelül 93 millió sort tartalmaz 157 táblában. Míg néhány ilyen táblázat alapvető adatokat tartalmaz, például előadókat, eseményeket, felvételeket, kiadásokat vagy számokat, mások link táblázatok — kapcsolatokat tárolnak az előadók és a felvételek, más előadók vagy kiadványok, stb. között... Egy adathalmaz gráfszerkezetét mutatják be. Amikor az adatkészletet RDF-hármasokká alakítottuk, körülbelül 500 millió példányt kaptunk.

Azon projektpartnerek tapasztalatai és benyomásai alapján, akikkel együtt dolgozunk, bemutatunk egy olyan környezetet, amelyben ez a tudásbázis új információk megszerzésére szolgál. Emellett elvárjuk, hogy rendszeresen frissítsék, például új kiadások hozzáadásával vagy a csoporttagok frissítésével.

beállítás

Ahogy az várható volt, az Amazon Neptune telepítése egyszerű. Elég részletes dokumentált. Néhány kattintással elindíthat egy grafikon adatbázist. Ha azonban részletesebb konfigurációról van szó, szükséges információ nehéz megtalálni. Ezért szeretnénk egy konfigurációs paraméterre mutatni.

Első benyomások az Amazon Neptune-ról
Konfigurációs képernyőkép a paramétercsoportokhoz

Az Amazon szerint a Neptune az alacsony késleltetésű tranzakciós terhelésekre összpontosít, ezért az alapértelmezett kérés időtúllépése 120 másodperc. Azonban számos olyan analitikai felhasználási esetet teszteltünk, amelyekben rendszeresen elértük ezt a határt. Ez az időkorlát megváltoztatható egy új paramétercsoport létrehozásával a Neptune számára és beállításával neptune_query_timeout megfelelő korlátozást.

adatok betöltése

Az alábbiakban részletesen tárgyaljuk, hogyan töltöttük be a MusicBrainz adatokat a Neptune-ba.

Kapcsolatok hármasban

Először a MusicBrainz adatokat RDF-hármasokká alakítottuk át. Ezért minden táblázathoz definiáltunk egy sablont, amely meghatározza, hogy az egyes oszlopok hogyan jelenjenek meg a hármasban. Ebben a példában az előadói táblázat minden sora tizenkét RDF-hármasra van leképezve.

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

tömeges feltöltés

A nagy mennyiségű adat Neptune-ba való betöltésének javasolt módja az S3-on keresztüli tömeges feltöltési folyamat. Miután feltöltötte hármas fájljait az S3-ba, a feltöltés POST-kéréssel kezdődik. A mi esetünkben 24 millió hármas esetében körülbelül 500 óra kellett. Arra számítottunk, hogy gyorsabb lesz.

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

Annak érdekében, hogy elkerüljük ezt a hosszadalmas folyamatot minden alkalommal, amikor elindítjuk a Neptune-t, úgy döntöttünk, hogy visszaállítjuk a példányt egy olyan pillanatképről, amelyben ezek a hármasok már betöltötték. A pillanatképből való futás lényegesen gyorsabb, de így is körülbelül egy óráig tart, amíg a Neptune elérhetővé válik a kérések számára.

Amikor először hármasokat töltöttünk be a Neptunba, különféle hibákat tapasztaltunk.

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

Némelyikük elemzési hiba volt, amint az fent látható. A mai napig még mindig nem jöttünk rá, hogy pontosan mi rontott el ezen a ponton. Egy kis részletezés biztosan segítene itt. Ez a hiba a beillesztett hármasok körülbelül 1%-ánál fordult elő. De ami a Neptune tesztelését illeti, elfogadtuk azt a tényt, hogy csak a MusicBrainz információinak 99%-ával dolgozunk.

Annak ellenére, hogy ez könnyű a SPARQL-t ismerő emberek számára, ne feledje, hogy az RDF-hármasokat explicit adattípusokkal kell ellátni, ami ismét hibákat okozhat.

Streaming letöltés

Ahogy fentebb említettük, a Neptunt nem statikus adattárként, hanem rugalmas és fejlődő tudásbázisként szeretnénk használni. Így meg kellett találnunk a módját, hogy új hármasokat vezessünk be, amikor a tudásbázis megváltozik, például amikor új albumot adnak ki, vagy ha a származtatott tudást szeretnénk materializálni.

A Neptune támogatja a bemeneti operátorokat a SPARQL lekérdezéseken keresztül, mind nyers, mind minta alapú. Az alábbiakban mindkét megközelítést tárgyaljuk.

Az egyik célunk az volt, hogy streaming módon vigyük be az adatokat. Fontolja meg egy album kiadását egy új országban. A MusicBrainz szemszögéből ez azt jelenti, hogy az albumokat, kislemezeket, EP-ket stb. tartalmazó kiadványok esetében új bejegyzés kerül a táblázatba kiadás-ország. Az RDF-ben ezt az információt két új hármassal párosítjuk.

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

A másik cél az volt, hogy új ismereteket szerezzünk a grafikonból. Tegyük fel, hogy meg akarjuk szerezni, hogy az egyes előadók hány kiadványt publikáltak pályafutása során. Egy ilyen lekérdezés meglehetősen összetett, és több mint 20 percet vesz igénybe a Neptune-ban, ezért az eredményt materializálnunk kell, hogy ezt az új tudást újra felhasználhassuk egy másik lekérdezésben. Így az ezzel az információval rendelkező hármasokat adjuk vissza a grafikonhoz, beírva a részlekérdezés eredményét.

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
 
}

Egyszeri hármasok hozzáadása a grafikonhoz néhány ezredmásodpercig tart, míg a részlekérdezés eredményének beszúrásához szükséges végrehajtási idő magának a részlekérdezésnek a végrehajtási idejétől függ.

Bár nem gyakran használtuk, a Neptune lehetővé teszi a hármasok eltávolítását is minták vagy explicit adatok alapján, amelyek segítségével frissíthető az információ.

SPARQL lekérdezések

Az előző részminta bemutatásával, amely az egyes előadók kiadásainak számát adja vissza, már bemutattuk az első típusú lekérdezést, amelyre a Neptune segítségével szeretnénk válaszolni. A lekérdezés felépítése a Neptune-ban egyszerű – küldjön egy POST kérést a SPARQL végpontnak az alábbiak szerint:

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

Ezenkívül megvalósítottunk egy lekérdezést, amely egy előadói profilt ad vissza, amely információkat tartalmaz a nevükről, életkorukról vagy származási országukról. Ne feledje, hogy az előadók lehetnek magánszemélyek, zenekarok vagy zenekarok. Ezen túlmenően ezeket az adatokat kiegészítjük az előadók által az év során megjelent kiadványok számával kapcsolatos információkkal. A szóló előadók esetében azokról a zenekarokról is adunk információkat, amelyekben az előadó minden évben részt vett.

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

Egy ilyen lekérdezés összetettsége miatt csak egy adott előadónál, például Elton Johnnál tudtunk pontlekérdezést végrehajtani, de nem minden előadónál. Úgy tűnik, hogy a Neptune nem optimalizálja az ilyen lekérdezéseket a szűrők részkijelölésekbe dobásával. Ezért minden egyes kijelölést manuálisan kell szűrni az előadó neve alapján.

A Neptune óránkénti és per-I/O töltésekkel is rendelkezik. Tesztelésünkhöz a minimális Neptune példányt használtuk, ami 0,384 USD/óra költséget jelent. A fenti lekérdezés esetében, amely egyetlen dolgozó profilját számítja ki, az Amazon több tízezer I/O műveletet számít fel ránk, ami 0.02 USD költséget jelent.

Teljesítmény

Először is, az Amazon Neptune betartja ígéreteinek nagy részét. Felügyelt szolgáltatásként ez egy grafikon adatbázis, amely rendkívül könnyen telepíthető, és sok konfiguráció nélkül is üzembe helyezhető. Íme az öt legfontosabb megállapításunk:

  • A tömeges feltöltés egyszerű, de lassú. De ez bonyolulttá válhat a nem túl hasznos hibaüzenetekkel.
  • A streaming letöltés mindent támogat, amire számítottunk, és meglehetősen gyors volt
  • A lekérdezések egyszerűek, de nem elég interaktívak az analitikus lekérdezések futtatásához
  • A SPARQL lekérdezéseket manuálisan kell optimalizálni
  • Az Amazon-fizetéseket nehéz megbecsülni, mert nehéz megbecsülni a SPARQL-lekérdezés által szkennelt adatok mennyiségét.

Ez minden. Jelentkezni valamire ingyenes webinárium a „Teherelosztás” témában.


Forrás: will.com

Hozzászólás