BerandaComputers and TechnologyMemgraphDB: Mengapa dan bagaimana kami mengimplementasikan Bolt Protocol v4

MemgraphDB: Mengapa dan bagaimana kami mengimplementasikan Bolt Protocol v4

Pengantar

Hari ini, dengan bangga kami mengumumkan rilis Memgraph 1.2 , yang secara signifikan meningkatkan kompatibilitas Memgraph dengan ekosistem grafik yang lebih luas. Ini memudahkan pengembang dan ilmuwan data untuk bekerja dengan Memgraph menggunakan alat favorit mereka.

Salah satu perubahan terbesar dalam rilis ini, adalah penambahan dukungan Bolt v4 dan v4.1.

Dalam posting ini, kita akan mengeksplorasi apa sebenarnya protokol Bolt, apa yang dibawanya ke tabel, dan bagaimana kita menerapkannya ke dalam Memgraph.

Protokol Baut

Jika Anda berpikir untuk menggunakan Memgraph di aplikasi Anda, salah satu dari persyaratan adalah kemungkinan menanyakan Memgraph langsung dari Anda aplikasi dengan upaya sesedikit mungkin. Anda dapat mencapainya dengan menulis driver untuk server Memgraph dalam bahasa yang ingin Anda dukung. Pengemudi adalah perpustakaan khusus yang mengikuti aturan yang telah ditentukan, alias protokol, untuk berkomunikasi aplikasi dan server Anda.

Alih-alih menetapkan aturannya sendiri, Memgraph memutuskan untuk menggunakan protokol Neo4j disebut Bolt . Ada 3 alasan penting untuk ini keputusan:

  1. Mendefinisikan protokol tidaklah mudah
  2. Neo4j juga menggunakan Cypher (itu tidak berarti bahwa Protokol baut tidak dapat digunakan untuk bahasa kueri lainnya!)
  3. Dengan mendukung protokol Neo4j, kami secara otomatis menjadi kompatibel dengan driver mereka

Driver yang saat ini dipelihara Neo4j adalah:

Dengan kata lain, dengan membuat server kami kompatibel dengan protokol Bolt, Anda dapat gunakan Memgraph dalam salah satu bahasa dan kerangka kerja yang tercantum di atas hanya dengan menggunakan Perpustakaan Neo4j.

Contoh Aturan Protokol Baut

Pertama, kita perlu tahu cara bertukar pesan. Bolt menukar pesannya menggunakan pola permintaan-respons antara klien dan server. Setiap pesan permintaan dapat diikuti dengan nol atau merekam pesan yang kemudian diikuti dengan satu pesan ringkasan. Berbagai kemungkinan untuk pesan rekaman tergantung pada jenis pesan permintaan.


CATATAN

Pesan catatan adalah jenis pesan yang berisi catatan, alias baris hasil.


Juga, kita perlu tahu bagaimana membuat serial data kita. Bolt menggunakan miliknya sendiri PackStream yang menyediakan spesifikasi untuk membuat serial dari berbagai jenis data . Ini sepenuhnya kompatibel dengan jenisnya didukung oleh Cypher. Kami tidak akan membahas detailnya, tetapi setiap jenis ditentukan dengan penanda, ukuran, dan datanya.

Sumber: https://7687.org/packstream/packstream -specification-1.html

Salah satunya adalah struktur. Ukuran struktur menentukan berapa banyak bidang itu berisi dan bidang bisa dari jenis lain. Tapi kami melewatkan informasi penting. Bagaimana kita tahu apa yang diwakili oleh struktur itu? Struktur membawa data tambahan, tag byte-nya. Tag ini memberitahu kita apa strukturnya mewakili. Sekarang kita setengah jalan untuk memahami cara menentukan permintaan dan pesan respons.

Kami tidak dapat berharap bahwa data kami akan selalu cukup kecil untuk mengirimkan semuanya sekali. Untuk mengatasi masalah ini, Bolt menentukan bagaimana pesan dipotong. Setiap potongan dimulai dengan header dua byte yang memberi tahu kita ukuran data potongan dalam byte diikuti oleh data potongan itu sendiri. Sekarang, kami punya masalah lain. Bagaimana kami bisa tahu jika kita menerima pesan terakhir? Kami baru saja menambahkan penanda! Dalam kasus kami, kami tambahkan ke akhir potongan terakhir 00 00 .

Sekarang, kami memiliki semua yang kami butuhkan untuk mendefinisikan pesan kami. Kita bisa mendefinisikan setiap tipe pesan permintaan / tanggapan sebagai struktur unik, memiliki sekumpulan bidang yang unik. Kami dapat mengirimkan struktur yang ditentukan menggunakan metode chunking yang ditentukan sebelumnya. Kami siap! Kami dapat membuat serial dan deserialisasi pesan sekarang!

Spesifikasi Protokol Baut

Spesifikasi protokol yang baik harus berisi informasi sebanyak mungkin. Tanpa informasi yang cukup, kita hanya bisa menebak bagaimana seharusnya server atau klien kita berperilaku dalam beberapa situasi, menyebabkan banyak sakit kepala untuk setiap pengembang itu mencoba menerapkan protokol itu.

Jadi, sebagai protokol yang baik, Bolt menentukan cara mengurai berbagai jenis permintaan pesan dan kirim pesan tanggapan yang benar. Ini mendefinisikan bagaimana setiap permintaan tampilan pesan dan apa yang harus dikirim sebagai pesan tanggapan di setiap kemungkinan situasi. Juga, ini mendefinisikan status server setelah setiap pesan permintaan dan hasilnya.

Jika ingin mendalami spesifikasi Bolt Protocol, Anda dapat menemukan semuanya di sini .


CATATAN

Menerapkan aturan tidaklah sulit, tetapi untuk melakukannya secara efisien membutuhkan banyak hal perencanaan yang cermat dan memiliki pemahaman yang baik tentang cara kerja protokol.


Evolusi Protokol Baut

Seperti perangkat lunak lainnya, protokol mudah berubah. Bolt mendefinisikannya versi menggunakan versi mayor dan minor. Di awal setiap koneksi, file klien perlu melakukan jabat tangan dengan server.

Jabat tangan sangat sederhana dan hanya terdiri dari dua langkah:

  • klien mengirim maksimal 4 versi yang didukungnya, diurutkan berdasarkan prioritas
  • server merespons dengan versi pertama dalam daftar yang didukungnya

Tetapi apakah Memgraph tidak mendukung protokol Bolt?

Ya, Memgraph mendukung protokol Bolt. Namun hingga saat ini, hanya mendukung Bolt v1, sedangkan versi saat ini adalah 4.1. Dengan melihat proses jabat tangan kami dapat menyimpulkan bahwa klien dapat mendukung paling banyak empat versi. Pemikiran logisnya adalah bahwa klien akan selalu mendukung 4 versi terbaru. Pada saat penulisan ini, versi terbaru adalah v4.1, yang mendorong v1 keluar dari daftar dukungan, membuat kami, dan semua orang yang ingin mencoba Memgraph menggunakan driver Neo4j, sangat sedih.


CATATAN

Penting untuk ditekankan bahwa setelah versi 1.0, versi yang lebih baru tidak didokumentasikan, yang membuat versi terbaru menjadi sangat sulit. Tapi, setelah v4.1, Neo4j memutuskan untuk mendokumentasikan setiap versi dengan baik sehingga membuat hidup kita lebih mudah. Terima kasih Neo4j!


The Road to Bolt v4. (1)

Karena Memgraph hanya kompatibel dengan versi pertama dari protokol Bolt, kami memiliki tiga perubahan versi mayor dan satu minor untuk diikuti.Sebagian besar hanya beberapa tambahan dasar untuk pesan yang sudah ada, tetapi ada ada juga beberapa perubahan yang lebih besar. Misalnya, kami membuat keputusan untuk mempertahankan dukungan untuk Bolt v1. Ini sangat menantang karena salah satu hal tersulit dalam pemrograman adalah membuat perubahan yang lebih besar pada kode yang ada sambil tidak merusak perilaku lama.

Mendukung banyak versi

Menangani kode yang berperilaku berbeda untuk setiap versi bisa jadi sulit. Setelah kita memutuskan versi untuk koneksi tertentu, kita perlu berhati-hati dengan pesan yang mana diizinkan untuk versi itu, respons mana yang harus dihasilkan oleh setiap pesan, apa parameter diperbolehkan, dan banyak lagi hal lainnya. Dan untuk melakukan itu sambil menggunakan kembali sebanyak mungkin kode mungkin, dengan tambahan menjaga keterbacaan bisa menjadi tantangan. Satu-satunya saran nyata yang dapat saya berikan kepada Anda di sini adalah menulis sebanyak mungkin tes yang akan mencakup semaksimal mungkin karena detail sekecil apapun bisa membuat server anda berfungsi sementara menerapkan dukungan untuk protokol.

Menjadikan penanganan transaksi lebih mudah dan lebih efektif

Di Bolt v3, pesan permintaan baru untuk menangani transaksi telah ditambahkan. Pesan-pesan itu adalah untuk memulai transaksi eksplisit dan mengakhiri transaksi pada melakukan atau mengembalikan perubahan. Karena kami sudah mendapat dukungan untuk transaksi dan Anda sudah bisa melakukannya hal yang sama dengan menjalankan kueri yang terdiri dari BEGIN , MELAKUKAN dan ROLLBACK perintah, satu-satunya hal yang harus kami lakukan adalah menambahkan fungsi yang secara langsung menjalankannya kueri saat permintaan terkait diterima.

Mendapatkan beberapa hasil dari sini dan beberapa dari sana

Perubahan terbesar pada protokol Bolt adalah perubahan ke TARIK dan MEMBUANG pesan. Sebelum kita mempelajari lebih dalam, mari kita jelaskan pesan-pesan tersebut. Saat Anda ingin menjalankan kueri di server menggunakan pesan Bolt, Anda perlu melakukannya terlebih dahulu kirim JALANKAN pesan yang berisi kueri yang ingin kami jalankan. Untuk mendapatkan hasil dari kueri yang kami kirimkan TARIK pesan, dan jika kita ingin membuang hasilnya, kami cukup mengirim DISCARD pesan. Cara alami menangani ini adalah mempersiapkan pertanyaan ketika kami menerima RUN pesan dan menjalankannya saat kami menerima TARIK pesan. Selain itu, untuk menghindari pemborosan memori, kami tidak menyimpan hasilnya, kami cukup teruskan ke pembuat enkode dan kirimkan langsung ke klien.

Di Bolt v1, ada PULL_ALL dan DISCARD_ALL pesan. Seperti namanya, satu-satunya pilihan yang Anda miliki adalah semua atau tidak sama sekali. Mempertimbangkan hal ini, kami berkembang solusi yang hanya akan mengalirkan semua hasil ke klien setelah diterima PULL_ALL pesan. Tapi, sejak v4.0, segalanya menjadi sedikit lebih rumit. The PULL_ALL pesan telah diubah namanya menjadi TARIK. Selain itu, TARIK pesan dapat datang dengan beberapa parameter tambahan.

n parameter

Sekarang Anda dapat menarik sejumlah hasil. Perubahan kecil ini menyiratkan banyak hal perubahan pada kode yang ada. Solusi termudah adalah dengan mengeksekusi kueri di pertama tarik dan simpan semua hasil di memori. Setelah itu, untuk setiap tarikan, kita baru saja kirim berikutnya n hasil. Meskipun ini adalah solusi termudah untuk diterapkan, itu juga memori tidak efisien. Mempertimbangkan hal ini, kami memiliki persyaratan yang sulit menjaga perilaku lama dan malas tanpa menyimpan hasil apa pun dalam memori.

Ada berbagai jenis kueri dan setiap kueri menuntut pendekatan yang berbeda mencapai perilaku ini. Kueri dengan ukuran hasil yang konstan, seperti pembuatan profil dan menjelaskan kueri, dapat memiliki vektor hasil sederhana dari mana hasilnya ditarik dengan malas. Untuk sebagian besar kueri yang memiliki ukuran variabel dari hasil, we persiapkan semua sumber daya yang diperlukan untuk pelaksanaan dan minta hasil berikutnya saja bila diperlukan, setelah itu hasilnya langsung dialirkan ke klien. Sumber daya dibersihkan setelah TARIK permintaan yang mengembalikan hasil terakhir. Ini dimungkinkan karena cara malas Memgraph dalam menangani eksekusi.

Kueri yang ternyata paling sulit diterapkan dengan malas adalah Kueri DUMP . Dengan sendirinya, sangat mudah untuk menerapkan kueri ini. Anda menganalisis berbagai bagian database Anda dan, sebagai hasilnya, mengirimkan kueri yang mendefinisikan bagian itu. Misalnya kita iterasi setiap simpul dalam database kami, dan kami mengirim kembali kueri untuk membuat simpul itu. Seperti yang kami katakan sebelumnya, membuat simpul hanyalah bagian dari DUMP hasil kueri. Kita harus melakukan hal yang sama untuk banyak bagian yang berbeda, seperti menentukan indeks dan batasan, dan dengan protokol Bolt baru kita perlu melakukan semuanya dengan malas. Itu artinya eksekusi dari DUMP kueri dapat berhenti di bagian mana pun, kapan pun. Solusi yang akhirnya kami lakukan adalah mendefinisikan setiap bagian sebagai bagian yang berdiri sendiri. Setiap potongan perlu melacak statusnya untuk melanjutkan dari tempat terakhirnya dan untuk mengetahui kapan selesai. Kami juga perlu mendefinisikan sebuah objek yang akan mengulang potongan tersebut, melanjutkan ke potongan berikutnya hanya jika yang sebelumnya sudah selesai. Dengan cara ini kita tidak perlu memikirkan bagian lain saat mendefinisikan setiap potongan. Kita dapat dengan mudah menambahkan potongan baru dengan mengimplementasikan antarmuka tertentu, dan yang lainnya yang penting adalah, tidak ada hasil yang disimpan dalam memori.

qid parameter

Saat dalam transaksi eksplisit, setiap RUN pesan mengembalikan qid yang secara unik mendefinisikan eksekusi itu. Menggunakan qid , kita dapat menarik dari setiap eksekusi yang belum selesai di dalam transaksi eksplisit kapan saja. Sepanjang perubahan kecil API mengembalikan qid , kita perlu menyimpan informasi tentang setiap eksekusi yang belum selesai. Tentu saja ada beberapa kenangan masalah di sana-sini, tetapi yang paling penting saat merancang solusi untuk ini adalah bagaimana Anda akan menemukan eksekusi yang diwakili oleh qid . Kami memutuskan untuk menggunakan qid sebagai indeks dari setiap eksekusi di dalam daftar eksekusi. Satu-satunya hal yang Anda butuhkan yang harus diperhatikan adalah menghapus kueri yang sudah selesai sehingga qid Anda dan indeks tidak keluar sinkronisasi.

Semua hal di atas berlaku untuk DISCARD_ALL pesan yang diubah namanya menjadi MEMBUANG.

Menangani DISCARD pesan

Dalam Memgraph versi sebelumnya, sebuah DISCARD_ALL pesan tidak menghasilkan perilaku yang benar. Sementara kami menerapkan protokol, satu-satunya informasi yang kami miliki adalah bahwa DISCARD_ALL pesan membuang semua hasil. Kami menyimpulkan bahwa ini berarti kami dapat mengabaikan eksekusi yang disiapkan dengan aman. Seperti yang kami ketahui nanti, dengan bantuan dari salah satu anggota komunitas kami, pesan ini seharusnya menjalankan kueri dan membuang semua hasil, yaitu hasil tidak boleh dialirkan. Kesalahan ini terlihat dengan menjalankan kueri dengan efek samping dan mengirimkan DISCARD_ALL . Kami memperbaikinya di versi terbaru server kami, tetapi ini adalah contoh yang bagus tentang bagaimana protokol harus selalu didefinisikan sedetail mungkin.

Mengikuti versi protokol Bolt yang akan datang

Kami berencana untuk mengikuti sebanyak mungkin versi terbaru dari protokol Bolt. Kumpulan 4 versi memberi kami kelonggaran, tetapi tugas kami adalah mengikuti versi terbaru driver Neo4j sehingga Anda dapat meminta Memgraph dari berbagai bahasa.

Driver Memgraph

Meskipun Memgraph mendukung driver Neo4j, kami juga mengembangkan driver kami sendiri menggunakan protokol Bolt untuk memberikan kinerja dan pengalaman pengembang yang lebih baik. Sejauh ini, kami telah menerapkan driver berikut:

Kesimpulan

Dalam posting blog ini kami menjelajahi apa artinya mendukung driver Neo4j dan mengapa tidak selalu mudah untuk mengikuti versi terbaru.

Sekarang Memgraph mendukung versi terbaru dari protokol Bolt, kami mendorong Anda untuk mencobanya dan memberi tahu kami pendapat Anda.

Anda dapat mendownload Memgraph terbaru di halaman download kami .

Jika Anda tidak dapat memberikan contoh untuk mencoba Memgraph, jangan khawatir, kami mengumpulkan contoh untuk setiap pengemudi yang didukung di Bagaimana Mengueri Memgraf Secara Terprogram? .

Selain itu, bug dan kesalahan selalu mungkin terjadi jadi jangan ragu untuk melaporkan perilaku aneh apa pun di forum.

Read More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments