Tere, Habri elanikud. Kursuse alguse eelÔhtul Oleme koostanud huvitava materjali tÔlke.

Paljudel kasutusjuhtudel, mida meie, nagu , nĂ€eme oma klientide veebisaitidel, et oluline teave on peidetud ĂŒksuste vahelistesse suhetesse, nĂ€iteks kasutajate vaheliste suhete, elementide vaheliste sĂ”ltuvuste vĂ”i andurite vaheliste seoste analĂŒĂŒsimisel. Selliseid kasutusjuhtumeid modelleeritakse tavaliselt graafikul. Selle aasta alguses avaldas Amazon uue graafikute andmebaasi Neptune. Selles postituses tahame jagada oma esimesi ideid, hĂ€id tavasid ja seda, mida saab aja jooksul paremaks muuta.
Miks me vajasime Amazon Neptuuni
Graafiandmebaasid lubavad omavahel tihedalt seotud andmekogumeid paremini kĂ€sitleda kui nende relatsioonilised vasted. Sellistes andmekogumites talletatakse asjakohane teave tavaliselt objektidevahelistes suhetes. Neptuuni testimiseks kasutasime hĂ€mmastavat avatud andmete projekti MusicBrainz kogub muusika kohta igasuguseid mĂ”eldavaid metaandmeid, nĂ€iteks teavet artistide, lugude, albumite ilmumise vĂ”i kontsertide kohta, aga ka seda, kellega loo loonud artist koostööd tegi vĂ”i millal ja millises riigis album vĂ€lja anti. MusicBrainzi vĂ”ib pidada tohutuks vĂ”rgustikuks ĂŒksustest, mis on kuidagi seotud muusikatööstusega.
MusicBrainzi andmestik on esitatud relatsioonandmebaasi CSV-tĂ”mmisena. Kokku sisaldab mĂ€lutĂ”mmis umbes 93 miljonit rida 157 tabelis. Kuigi mĂ”ned neist tabelitest sisaldavad pĂ”hiandmeid, nagu artistid, sĂŒndmused, salvestised, vĂ€ljaanded vĂ”i lood, sisaldavad teised jĂ€rgmist: linkige tabeleid â salvestab seoseid artistide ja plaatide, teiste artistide vĂ”i vĂ€ljaannete vahel jne. Need demonstreerivad andmestiku graafistruktuuri. Kui me teisendasime andmestiku RDF-kolmikfailideks, saime umbes 500 miljonit eksemplari.
Projektipartnerite, kellega koostööd teeme, kogemuste ja muljete pÔhjal kujutame ette keskkonda, kus seda teadmusbaasi kasutatakse uue teabe hankimiseks. Lisaks eeldame, et seda ajakohastatakse regulaarselt, nÀiteks uute vÀljaannete lisamise vÔi grupi liikmete nimekirja uuendamise teel.
reguleerimine
Nagu arvata vĂ”is, on Amazon Neptune'i installimine lihtne. See on ĂŒsna detailne. Graafiandmebaasi saab kĂ€ivitada vaid mĂ”ne klĂ”psuga. TĂ€psema konfiguratsiooni osas aga... raske leida. SeetĂ”ttu tahame viidata ĂŒhele konfiguratsiooniparameetrile.

ParameetrirĂŒhmade konfiguratsiooni ekraanipilt
Amazon vĂ€idab, et Neptune keskendub madala latentsusega tehingute töökoormustele, seega on pĂ€ringu vaikimisi ajalĂ”pp 120 sekundit. Siiski testisime paljusid analĂŒĂŒtika kasutusjuhtumeid, kus me regulaarselt selle piirini jĂ”udsime. Seda ajalĂ”ppu saab muuta, luues Neptune'ile uue parameetrirĂŒhma ja mÀÀrates selle vÀÀrtuseks neptune_query_timeout vastav piirang.
Andmete laadimine
Allpool arutame ĂŒksikasjalikumalt, kuidas me MusicBrainzi andmeid Neptune'i laadisime.
Suhted kolmekesi
Esmalt teisendasime MusicBrainzi andmed RDF-kolmikeks. Seega iga tabeli jaoks defineerisime malli, mis mÀÀrab, kuidas iga veergu kolmikus esitatakse. Selles nĂ€ites on iga artisti tabeli rida kaardistatud kaheteistkĂŒmneks RDF-kolmikeks.
<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> .
Massiline ĂŒleslaadimine
Soovitatav viis suurte andmemahtude ĂŒleslaadimiseks Neptune'i on hulgiĂŒleslaadimise protsess S3 kaudu. Kui teie kolmikfailid on S3-sse ĂŒles laaditud, alustate ĂŒleslaadimist POST-pĂ€ringuga. Meie puhul kulus 24 miljoni kolmikfaili laadimiseks umbes 500 tundi. Me eeldasime, et see on kiirem.
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"
}'Selle pika protsessi vÀltimiseks iga kord, kui Neptune'i kÀivitame, otsustasime taastada eksemplari hetktÔmmisest, kuhu need kolmikud juba laaditud on. HetktÔmmisest kÀivitamine on oluliselt kiirem, kuid vÔtab siiski umbes tunni, enne kui Neptune pÀringuteks saadaval on.
Kolmikute esialgsel laadimisel Neptuuni sattusime mitmesugustesse vigadesse.
{
"errorCode" : "PARSING_ERROR",
"errorMessage" : "Content after '.' is not allowed",
"fileName" : [...],
"recordNum" : 25
}MĂ”ned neist olid parsimisvead, nagu eespool nĂ€idatud. TĂ€nase seisuga pole me ikka veel aru saanud, mis tĂ€pselt valesti lĂ€ks. Natuke rohkem ĂŒksikasju oleks siinkohal kindlasti abiks. See viga esines umbes 1% sisestatud kolmikute puhul. Aga Neptuuni testimisel oleme leppinud tĂ”siasjaga, et töötame ainult 99% MusicBrainzi teabega.
Kuigi see pole SPARQL-iga tuttavatele probleem, pidage meeles, et RDF-kolmikud tuleb annoteerida selgesĂ”naliste andmetĂŒĂŒpidega, mis vĂ”ib jĂ€llegi olla veaohtlik.
Voogesituse allalaadimine
Nagu eespool mainitud, ei taha me Neptune'i kasutada staatilise andmehoidlana, vaid pigem paindliku ja areneva teadmusbaasina. Seega pidime leidma viise uute kolmikute lisamiseks, kui teadmusbaas muutub, nÀiteks uue albumi ilmumisel vÔi tuletatud teadmiste materialiseerimisel.
Neptune toetab sisestusoperaatoreid SPARQL pÀringute kaudu, nii toor- kui ka nÀidispÔhiste andmete puhul. MÔlemat lÀhenemisviisi kÀsitleme allpool.
Ăks meie eesmĂ€rkidest oli sisestada andmeid voogedastusviisil. Kaaluge albumi vĂ€ljaandmist uues riigis. MusicBrainzi vaatenurgast tĂ€hendab see, et albumeid, singleid, EP-sid jne sisaldava vĂ€ljaande puhul lisatakse tabelisse uus kirje. vĂ€ljalaskeriikRDF-is kaardistame selle teabe kaheks uueks kolmikuks.
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> };Teine eesmĂ€rk oli graafikult uut teavet ammutada. Oletame, et tahame teada saada, mitu vĂ€ljaannet on iga artist oma karjÀÀri jooksul avaldanud. See pĂ€ring on ĂŒsna keeruline ja vĂ”tab Neptune'is rohkem kui 20 minutit, seega peame tulemuse materialiseerima, et seda uut teavet mĂ”nes teises pĂ€ringus taaskasutada. Seega lisame selle teabega kolmikud tagasi graafikule, sisestades alampĂ€ringu tulemuse.
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
}Ăksikute kolmikute lisamine graafikule vĂ”tab paar millisekundit, samas kui alampĂ€ringu tulemuse sisestamise tĂ€itmisaeg sĂ”ltub alampĂ€ringu enda tĂ€itmisajast.
Kuigi me seda palju ei kasutanud, vÔimaldab Neptune teil eemaldada ka kolmikuid valimite vÔi selgesÔnaliste andmete pÔhjal, mida saab kasutada teabe vÀrskendamiseks.
SPARQL pÀringud
Eelmise alamhulga kasutuselevĂ”tuga, mis tagastab iga esineja vĂ€ljalasete arvu, oleme juba tutvustanud esimest pĂ€ringutĂŒĂŒpi, millele tahame Neptune'i abil vastata. PĂ€ringu koostamine Neptune'is on lihtne â saatke lihtsalt POST-pĂ€ring SPARQL-i lĂ”pp-punkti, nagu allpool nĂ€idatud:
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/sparqlLisaks oleme rakendanud pĂ€ringu, mis tagastab artisti profiili, mis sisaldab teavet tema nime, vanuse vĂ”i pĂ€ritoluriigi kohta. Pidage meeles, et artistid vĂ”ivad olla ĂŒksikisikud, ansamblid vĂ”i orkestrid. Lisaks tĂ€iendame neid andmeid teabega artisti aasta jooksul vĂ€lja antud vĂ€ljaannete arvu kohta. Sooloartistide puhul lisame ka teabe bĂ€ndide kohta, mille liige nad igal aastal on olnud.
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)
}Selle pÀringu keerukuse tÔttu saime punktpÀringuid teha ainult konkreetse artisti, nÀiteks Elton Johni, kuid mitte kÔigi artistide kohta. Neptune ei paista seda pÀringut filtrite lisamisega alamvalikutesse optimeerivat. SeetÔttu tuleb iga valikut artisti nime jÀrgi kÀsitsi filtreerida.
Neptune'il on nii tunnipĂ”hine kui ka IO-pĂ”hine hinnakujundus. Testimiseks kasutasime vĂ€ikseimat Neptune'i eksemplari, mille tunnihind on 0,384 dollarit. Ălaltoodud pĂ€ringu puhul, mis arvutab ĂŒhe töötaja profiili, kĂŒsib Amazon meilt kĂŒmneid tuhandeid I/O-sid, mis tĂ€hendab 0.02 dollari suurust hinda.
VĂ€ljund
Esiteks, Amazon Neptune tÀidab enamiku oma lubadustest. Hallatava teenusena on see graafiline andmebaas, mida on uskumatult lihtne seadistada ja mis saab ilma suurema konfigureerimiseta tööle panna. Siin on meie viis peamist jÀreldust:
- Massiline ĂŒleslaadimine on lihtne, aga aeglane. Seda vĂ”ivad aga keeruliseks teha mitte eriti abivalmid veateated.
- Voogesituse allalaadimised toetasid kÔike, mida ootasime, ja olid mÔistlikult kiired
- PĂ€ringud on lihtsad, kuid mitte piisavalt interaktiivsed analĂŒĂŒtiliste pĂ€ringute tegemiseks.
- SPARQL pÀringud tuleb kÀsitsi optimeerida
- Amazoni tasusid on raske hinnata, kuna SPARQL-pÀringuga skannitud andmete hulka on keeruline hinnata.
See on praegu kÔik. Registreeru .
Allikas: www.habr.com
