Kesan Pertama Amazon Neptunus

Salute, Khabrovsk. Untuk mengantisipasi dimulainya kursus AWS untuk Pengembang, kami menyiapkan terjemahan materi yang menarik.




Dalam banyak kasus pengguna yang kami, sebagai bakdata , lihat di situs pelanggan kami, informasi yang relevan disembunyikan dalam hubungan antar entitas, misalnya, ketika menganalisis hubungan antar pengguna, ketergantungan antar elemen, atau koneksi antar sensor. Kasus pengguna seperti itu biasanya dimodelkan pada grafik. Awal tahun ini, Amazon merilis basis data grafik Neptunus yang baru. Dalam posting ini, kami ingin membagikan ide pertama kami, praktik yang baik, dan apa yang dapat ditingkatkan dari waktu ke waktu.

Mengapa kita membutuhkan Amazon Neptune


Database grafik berjanji untuk menangani dataset yang sangat terhubung dengan lebih baik daripada padanan relasionalnya. Dalam kumpulan data tersebut, informasi yang relevan biasanya disimpan dalam hubungan antar objek. Untuk menguji Neptunus kami menggunakan proyek luar biasa dengan data terbuka MusicBrainz . MusicBrainz mengumpulkan setiap metadata yang dapat dibayangkan tentang musik, misalnya, informasi tentang artis, lagu, rilis atau konser album, serta siapa artis yang membuat lagu tersebut berkolaborasi dengan atau ketika album dirilis di negara mana. MusicBrainz dapat dilihat sebagai jaringan besar entitas yang entah bagaimana terkait dengan industri musik.

Dataset MusicBrainz disediakan sebagai dump dari basis data relasional CSV. Secara total, dump berisi sekitar 93 juta baris dalam 157 tabel. Sementara beberapa tabel ini berisi data master, seperti artis, acara, catatan, rilis atau trek, yang lain - tabel tautan - menyimpan hubungan antara artis dan catatan, artis atau rilis lain, dll ... Mereka menunjukkan struktur grafis set data. Saat mengonversi kumpulan data menjadi RDF tiga kali lipat, kami mendapat sekitar 500 juta salinan.

Berdasarkan pengalaman dan kesan dari mitra proyek dengan siapa kami bekerja, kami menyajikan pengaturan di mana basis pengetahuan ini digunakan untuk mendapatkan informasi baru. Selain itu, kami menganggap bahwa itu akan diperbarui secara berkala, misalnya, dengan menambahkan rilis baru atau memperbarui anggota grup.

Kustomisasi


Seperti yang diharapkan, menginstal Amazon Neptune mudah. Ini didokumentasikan dalam beberapa detail . Anda dapat memulai basis data grafik hanya dengan beberapa klik. Namun, ketika datang ke konfigurasi yang lebih rinci, informasi yang Anda butuhkan sulit ditemukan. Oleh karena itu, kami ingin menunjukkan satu parameter konfigurasi.


Tangkapan layar konfigurasi untuk grup parameter

Amazon mengklaim bahwa Neptunus berfokus pada beban kerja transaksional latensi rendah, sehingga batas waktu default adalah 120 detik. Namun, kami menguji banyak kasus pengguna analitis di mana kami secara teratur mencapai batas ini. Anda dapat mengubah batas waktu ini dengan membuat grup parameter baru untuk Neptunus dan mengaturnya menjadineptune_query_timeout pembatasan yang sesuai.

Pemuatan data


Di bawah ini kita akan membahas secara rinci bagaimana kami mengunggah data MusicBrainz ke Neptune.

Hubungan di bertiga


Pertama, kami mengonversi data MusicBrainz menjadi tiga kali lipat RDF. Oleh karena itu, untuk setiap tabel, kami menetapkan template yang menentukan bagaimana setiap kolom diwakili dalam tiga teratas. Dalam contoh ini, setiap baris dari tabel pelaksana dipetakan menjadi dua belas RDF tiga kali lipat.

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


Unggahan massal


Metode yang diusulkan untuk memuat sejumlah besar data ke Neptunus adalah proses pemuatan massal melalui S3. Setelah mengunggah file tiga kali lipat Anda ke S3, Anda mulai mengunduh menggunakan permintaan POST. Dalam kasus kami, butuh sekitar 24 jam untuk 500 juta kali lipat. Kami berharap ini lebih cepat.

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

Untuk menghindari proses panjang ini setiap kali kami meluncurkan Neptunus, kami memutuskan untuk memulihkan instance dari snapshot yang memuat tiga kali lipat ini. Mulai dari snapshot jauh lebih cepat, tetapi masih membutuhkan waktu sekitar satu jam hingga Neptunus tersedia untuk permintaan.

Ketika awalnya memuat tiga kali lipat di Neptunus, kami menemukan berbagai kesalahan.

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

Beberapa di antaranya kesalahan parsing, seperti yang ditunjukkan di atas. Sampai saat ini, kami masih belum menemukan apa yang salah pada saat ini. Sedikit lebih detail pasti akan membantu di sini. Kesalahan ini terjadi sekitar 1% dari tiga kali lipat yang dimasukkan. Tetapi untuk pengujian Neptunus, kami menerima kenyataan bahwa kami hanya bekerja dengan 99% informasi dari MusicBrainz.

Sekalipun mudah bagi orang yang terbiasa dengan SPARQL, perlu diingat bahwa RDF tiga kali lipat harus dijelaskan dengan tipe data eksplisit, yang lagi-lagi dapat menyebabkan kesalahan.

Pengunduhan streaming


Seperti disebutkan di atas, kami tidak ingin menggunakan Neptunus sebagai gudang data statis, melainkan sebagai basis pengetahuan yang fleksibel dan berkembang. Oleh karena itu, kami perlu menemukan cara untuk memperkenalkan tiga kali lipat baru ketika mengubah basis pengetahuan, misalnya, ketika album baru diterbitkan atau ketika kami ingin mematerialisasikan pengetahuan yang diperoleh.

Neptunus mendukung operator input melalui kueri SPARQL, baik dengan data mentah maupun berdasarkan sampel. Kami akan membahas kedua pendekatan di bawah ini.

Salah satu tujuan kami adalah memasukkan data dalam mode streaming. Pertimbangkan rilis album di negara baru. Dari sudut pandang MusicBrainz, ini berarti bahwa untuk rilis yang mencakup album, single, EP, dll., Catatan baru ditambahkan ke tabel negara rilis. Dalam RDF, kami membandingkan informasi ini dengan dua kali lipat baru.

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

Tujuan lain adalah untuk mendapatkan pengetahuan baru dari grafik. Misalkan kita ingin mendapatkan jumlah rilis yang telah diterbitkan masing-masing artis dalam kariernya. Permintaan semacam itu agak rumit dan membutuhkan lebih dari 20 menit di Neptunus, jadi kita perlu mematerialisasikan hasilnya untuk menggunakan kembali pengetahuan baru ini di beberapa permintaan lainnya. Oleh karena itu, kami menambahkan tiga kali lipat dengan informasi ini kembali ke grafik, memperkenalkan hasil dari subquery.

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
 
}

Menambahkan tiga kali lipat ke grafik membutuhkan beberapa milidetik, sementara waktu eksekusi untuk memasukkan hasil subquery tergantung pada waktu eksekusi subquery itu sendiri.

Terlepas dari kenyataan bahwa kami tidak sering menggunakannya, Neptunus juga memungkinkan Anda untuk menghapus tiga kali lipat berdasarkan sampel atau data eksplisit yang dapat digunakan untuk memperbarui informasi.

Kueri SPARQL


Memperkenalkan subsampel sebelumnya, yang mengembalikan jumlah rilis untuk setiap artis, kami telah memperkenalkan jenis permintaan pertama yang ingin kami jawab menggunakan Neptunus. Membuat kueri di Neptunus itu mudah - kirim permintaan POST ke titik akhir SPARQL, seperti yang ditunjukkan di bawah ini:

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

Selain itu, kami menerapkan kueri yang menampilkan profil artis yang berisi informasi tentang nama, usia, atau negara asal mereka. Perlu diingat bahwa pelaku bisa orang, kelompok, atau orkestra. Selain itu, kami melengkapi data ini dengan informasi tentang jumlah rilis yang dirilis oleh artis selama tahun tersebut. Untuk artis solo, kami juga menambahkan informasi tentang grup di mana artis ini berpartisipasi dalam setiap tahun.

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

Karena kerumitan permintaan seperti itu, kami hanya dapat melakukan permintaan titik untuk artis tertentu, seperti Elton John, tetapi tidak untuk semua artis. Neptunus tampaknya tidak mengoptimalkan permintaan seperti itu dengan menghilangkan filter dalam subsamples. Karena itu, setiap sampel harus disaring secara manual dengan nama artis.

Neptunus memiliki setiap jam dan membayar untuk setiap operasi I / O. Untuk pengujian kami, kami menggunakan contoh Neptunus terkecil, yang harganya $ 0,384 / jam. Dalam kasus permintaan di atas, yang menghitung profil untuk satu artis, Amazon akan menagih kepada kami puluhan ribu I / O, yang menyiratkan biaya $ 0,02.

Kesimpulan


Pertama, Amazon Neptunus menepati sebagian besar janjinya. Menjadi layanan yang dikelola, ini adalah basis data grafik yang sangat mudah untuk diinstal dan dapat diluncurkan tanpa banyak pengaturan. Berikut ini lima temuan utama kami:

  • Unggahan massal sederhana namun lambat. Tapi itu bisa menjadi rumit karena pesan kesalahan yang tidak banyak membantu
  • Pemuatan aliran mendukung semua yang kami harapkan, dan cukup cepat
  • Kueri sederhana tetapi tidak cukup interaktif untuk melakukan kueri analitik
  • Kueri SPARQL harus dioptimalkan secara manual
  • Pembayaran Amazon sulit untuk dievaluasi karena sulit untuk memperkirakan jumlah data yang dipindai oleh permintaan SPARQL.

Itu saja. Mendaftar untuk webinar gratis dengan topik โ€œLoad Balancingโ€ .

All Articles