Buku Besar Terdistribusi untuk Roda: Pengalaman dengan Hyperledger Fabric

Halo, Saya bekerja di tim proyek DRD KP (registrasi data terdistribusi untuk memantau siklus hidup set roda). Di sini saya ingin berbagi pengalaman tim kami dalam mengembangkan blockchain perusahaan untuk proyek ini di bawah batasan teknologi. Saya sebagian besar akan berbicara tentang Hyperledger Fabric, tetapi pendekatan yang dijelaskan di sini dapat diekstrapolasi ke blockchain mana pun yang berizin. Tujuan akhir dari penelitian kami adalah untuk mempersiapkan solusi blockchain perusahaan sehingga produk akhir menyenangkan untuk digunakan dan tidak terlalu sulit untuk dipelihara.

Tidak akan ada penemuan, solusi yang tidak terduga, dan tidak ada perkembangan unik yang akan dibahas di sini (karena saya tidak memilikinya). Saya hanya ingin berbagi pengalaman sederhana saya, menunjukkan bahwa "itu mungkin" dan, mungkin, membaca tentang pengalaman orang lain dalam membuat keputusan yang baik dan tidak terlalu baik di komentar.

Masalah: blockchain belum dapat diskalakan

Saat ini, upaya banyak pengembang ditujukan untuk menjadikan blockchain sebagai teknologi yang benar-benar nyaman, dan bukan bom waktu yang dibungkus dengan indah. Saluran negara, rollup optimis, plasma, dan sharding mungkin akan menjadi hal biasa. Suatu hari nanti. Atau mungkin TON akan kembali menunda peluncurannya selama enam bulan, dan Grup Plasma berikutnya akan lenyap. Kita bisa percaya pada peta jalan berikutnya dan membaca kertas putih yang cemerlang di malam hari, namun saat ini kita perlu melakukan sesuatu dengan apa yang kita miliki. Selesaikan semuanya.

Tugas yang diberikan kepada tim kami dalam proyek saat ini secara umum terlihat seperti ini: ada banyak subjek, mencapai beberapa ribu, yang tidak ingin membangun hubungan berdasarkan kepercayaan; perlu untuk membangun solusi DLT yang akan bekerja pada PC biasa tanpa persyaratan kinerja khusus dan memberikan pengalaman pengguna yang tidak lebih buruk daripada sistem akuntansi terpusat mana pun. Teknologi di balik solusi ini harus meminimalkan kemungkinan manipulasi data yang berbahaya - itulah mengapa blockchain ada di sini.

Slogan dari whitepaper dan media menjanjikan kita bahwa perkembangan selanjutnya akan memungkinkan kita melakukan jutaan transaksi per detik. Apa itu sebenarnya?

Mainnet Ethereum saat ini berjalan pada ~30 tps. Karena hal ini saja, sulit untuk menganggapnya sebagai blockchain yang sesuai untuk kebutuhan perusahaan. Di antara solusi yang diizinkan, tolok ukur yang menunjukkan 2000 tps diketahui (kuorum) atau 3000 tps (Kain Hyperledger, ada sedikit lebih sedikit dalam publikasi, namun perlu diingat bahwa benchmark dilakukan pada mesin konsensus lama). Dulu upaya pemrosesan Fabric secara radikal, yang tidak memberikan hasil terburuk, 20000 tps, namun sejauh ini hanya kajian akademis yang menunggu implementasi stabil. Kecil kemungkinannya bahwa perusahaan yang mampu mempertahankan departemen pengembang blockchain akan menerima indikator seperti itu. Namun masalahnya bukan hanya pada throughput saja, ada juga latensi.

Latensi

Penundaan dari saat transaksi dimulai hingga persetujuan akhir oleh sistem tidak hanya bergantung pada kecepatan pesan melewati semua tahap validasi dan pemesanan, tetapi juga pada parameter pembentukan blok. Bahkan jika blockchain kita memungkinkan kita untuk berkomitmen pada 1000000 tps, namun dibutuhkan 10 menit untuk membentuk blok 488MB, apakah akan lebih mudah bagi kita?

Mari kita lihat lebih dekat siklus hidup suatu transaksi di Hyperledger Fabric untuk memahami apa yang membutuhkan waktu dan bagaimana kaitannya dengan parameter pembentukan blok.

Buku Besar Terdistribusi untuk Roda: Pengalaman dengan Hyperledger Fabric
diambil dari sini: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Klien membentuk transaksi, mengirimkannya ke rekan pendukung, yang terakhir mensimulasikan transaksi (menerapkan perubahan yang dibuat oleh kode rantai ke keadaan saat ini, tetapi tidak berkomitmen ke buku besar) dan menerima RWSet - nama kunci, versi dan nilai yang diambil dari koleksi di CouchDB, (2) endorser mengirim RWSet yang ditandatangani kembali ke klien, (3) klien memeriksa tanda tangan semua rekan yang diperlukan (endorser), dan kemudian mengirimkan transaksi ke layanan pemesanan , atau mengirimkannya tanpa verifikasi (verifikasi tetap dilakukan nanti), layanan pemesanan membentuk blok dan (4) mengirimkan kembali ke semua rekan, bukan hanya endorser; rekan-rekan memeriksa bahwa versi kunci dalam set baca cocok dengan versi dalam database, tanda tangan semua pendukung, dan akhirnya melakukan pemblokiran.

Tapi itu belum semuanya. Kata-kata "pemesan membentuk blok" tidak hanya menyembunyikan urutan transaksi, tetapi juga 3 permintaan jaringan berurutan dari pemimpin ke pengikut dan sebaliknya: pemimpin menambahkan pesan ke log, mengirimkannya ke pengikut, yang terakhir menambahkannya ke log mereka, mengirimkan konfirmasi keberhasilan replikasi kepada pemimpin, pemimpin melakukan pesan, mengirimkan konfirmasi melakukan kepada pengikut, pengikut melakukan. Semakin kecil ukuran dan waktu pembentukan blok, semakin sering layanan pemesanan harus mencapai konsensus. Hyperledger Fabric memiliki dua parameter untuk pembentukan blok: BatchTimeout - waktu pembentukan blok dan BatchSize - ukuran blok (jumlah transaksi dan ukuran blok itu sendiri dalam byte). Segera setelah salah satu parameter mencapai batasnya, blok baru dikeluarkan. Semakin banyak node pemesan, semakin lama waktu yang dibutuhkan. Oleh karena itu, Anda perlu meningkatkan BatchTimeout dan BatchSize. Namun karena RWSet memiliki versi, semakin besar blok yang kita buat, semakin tinggi kemungkinan konflik MVCC. Selain itu, dengan meningkatnya BatchTimeout, UX menurun secara drastis. Bagi saya, skema berikut untuk memecahkan masalah ini masuk akal dan jelas.

Bagaimana menghindari menunggu penyelesaian blok dan tidak kehilangan kemampuan untuk melacak status transaksi

Semakin lama waktu pembentukan dan ukuran blok, semakin tinggi throughput blockchain tersebut. Yang satu tidak secara langsung mengikuti yang lain, namun harus diingat bahwa membangun konsensus dalam RAFT memerlukan tiga permintaan jaringan dari pemimpin ke pengikut dan sebaliknya. Semakin banyak node pesanan, semakin lama waktu yang dibutuhkan. Semakin kecil ukuran dan waktu pembentukan blok, semakin banyak interaksi yang terjadi. Bagaimana cara meningkatkan waktu pembentukan dan ukuran blok tanpa menambah waktu respons sistem untuk pengguna akhir?

Pertama, kita perlu menyelesaikan konflik MVCC yang disebabkan oleh ukuran blok yang besar, yang mungkin mencakup RWSet berbeda dengan versi yang sama. Jelas, di sisi klien (dalam kaitannya dengan jaringan blockchain, ini bisa jadi merupakan backend, dan yang saya maksudkan) Anda memerlukan Penangan konflik MVCC, yang dapat berupa layanan terpisah atau dekorator reguler di atas panggilan yang memulai transaksi dengan logika percobaan ulang.

Percobaan ulang dapat diterapkan dengan strategi eksponensial, tetapi latensi juga akan menurun secara eksponensial. Jadi, Anda harus menggunakan percobaan ulang secara acak dalam batas kecil tertentu, atau percobaan ulang yang konstan. Dengan memperhatikan kemungkinan tabrakan pada varian pertama.

Langkah selanjutnya adalah membuat interaksi klien dengan sistem menjadi asynchronous sehingga tidak menunggu selama 15, 30 atau 10000000 detik yang akan kita atur sebagai BatchTimeout. Namun pada saat yang sama, penting untuk menjaga kemampuan untuk memverifikasi bahwa perubahan yang dimulai oleh transaksi dicatat/tidak dicatat dalam blockchain.
Database dapat digunakan untuk menyimpan status transaksi. Opsi termudah adalah CouchDB karena kemudahan penggunaannya: database memiliki UI yang siap digunakan, REST API, dan Anda dapat dengan mudah menyiapkan replikasi dan sharding untuknya. Anda cukup membuat koleksi terpisah di instance CouchDB yang sama yang digunakan Fabric untuk menyimpan status dunianya. Kita perlu menyimpan dokumen semacam ini.

{
 Status string // Бтатус Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ: "pending", "done", "failed"
 TxID: string // ID Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
 Error: string // optional, сообщСниС ΠΎΠ± ошибкС
}

Dokumen ini ditulis ke database sebelum transaksi dikirim ke rekan-rekan, ID entitas dikembalikan ke pengguna (ID yang sama digunakan sebagai kunci) jika ini adalah operasi pembuatan, dan kemudian bidang Status, TxID dan Error adalah diperbarui ketika informasi relevan diterima dari rekan-rekan.

Buku Besar Terdistribusi untuk Roda: Pengalaman dengan Hyperledger Fabric

Dalam skema ini, pengguna tidak menunggu hingga blok akhirnya terbentuk, mengamati roda yang berputar di layar selama 10 detik, ia menerima respons instan dari sistem dan terus bekerja.

Kami memilih BoltDB untuk menyimpan status transaksi karena kami perlu menghemat memori dan tidak ingin membuang waktu berinteraksi jaringan dengan server database yang berdiri sendiri, terutama ketika interaksi ini menggunakan protokol teks biasa. Omong-omong, apakah Anda menggunakan CouchDB untuk mengimplementasikan skema yang dijelaskan di atas atau hanya untuk menyimpan status dunia, dalam hal apa pun, masuk akal untuk mengoptimalkan cara data disimpan di CouchDB. Secara default, di CouchDB, ukuran node b-tree adalah 1279 byte, yang jauh lebih kecil dari ukuran sektor pada disk, yang berarti bahwa pembacaan dan penyeimbangan ulang pohon akan memerlukan lebih banyak akses disk fisik. Ukuran optimal memenuhi standar Format Lanjutan dan 4 kilobyte. Untuk mengoptimalkan kita perlu mengatur parameternya btree_chunk_size sama dengan 4096 di file konfigurasi CouchDB. Untuk BoltDB intervensi manual seperti itu tidak diperlukan.

Tekanan balik: strategi penyangga

Tapi pesannya bisa banyak. Lebih dari yang dapat ditangani oleh sistem, berbagi sumber daya dengan selusin layanan lain selain yang ditunjukkan dalam diagram - dan semua ini akan bekerja dengan sempurna bahkan pada mesin yang menjalankan Intellij Idea akan sangat membosankan.

Masalah perbedaan throughput sistem komunikasi, produsen dan konsumen, diselesaikan dengan cara yang berbeda. Mari kita lihat apa yang bisa kita lakukan.

Jatuhan: Kami dapat mengklaim bahwa kami mampu memproses paling banyak X transaksi dalam T detik. Semua permintaan yang melebihi batas ini akan dibuang. Ini cukup sederhana, tetapi Anda bisa melupakan UX.

Mengontrol: konsumen harus memiliki semacam antarmuka yang melaluinya, tergantung pada bebannya, ia dapat mengontrol TPS produsen. Lumayan, tapi ini membebankan kewajiban pada pengembang klien yang membuat beban untuk mengimplementasikan antarmuka ini. Hal ini tidak dapat kami terima, karena blockchain di masa depan akan diintegrasikan ke dalam sejumlah besar sistem yang sudah lama ada.

Buffering: Daripada mencoba menolak aliran data masukan, kita dapat melakukan buffer aliran ini dan memprosesnya pada kecepatan yang diperlukan. Tentunya ini adalah solusi terbaik jika kita ingin memberikan pengalaman pengguna yang baik. Kami mengimplementasikan buffer menggunakan antrian di RabbitMQ.

Buku Besar Terdistribusi untuk Roda: Pengalaman dengan Hyperledger Fabric

Dua tindakan baru telah ditambahkan ke skema: (1) setelah permintaan ke API tiba, pesan dengan parameter yang diperlukan untuk memanggil transaksi ditempatkan dalam antrian, dan klien menerima pesan bahwa transaksi telah diterima oleh sistem, (2) backend membaca data dengan kecepatan yang ditentukan dalam konfigurasi dari antrian; memulai transaksi dan memperbarui data di penyimpanan status.
Sekarang Anda dapat meningkatkan waktu pembentukan dan kapasitas blok sebanyak yang Anda inginkan, menyembunyikan penundaan dari pengguna.

Alat lainnya

Tidak ada yang dikatakan di sini tentang kode rantai, karena, sebagai aturan, tidak ada yang perlu dioptimalkan di dalamnya. Chaincode harus sesederhana dan seaman mungkin - hanya itu yang diperlukan. Kerangka kerja ini membantu kita menulis kode rantai dengan sederhana dan aman CSKit dari S7 Techlab dan penganalisis statis hidupkan kembali ^ CC.

Selain itu, tim kami sedang mengembangkan serangkaian utilitas untuk membuat bekerja dengan Fabric menjadi sederhana dan menyenangkan: penjelajah blockchain, utilitas untuk perubahan konfigurasi jaringan otomatis (menambah/menghapus organisasi, node RAFT), utilitas untuk pencabutan sertifikat dan penghapusan identitas. Jika Anda ingin berkontribusi, silakan.

Kesimpulan

Pendekatan ini memudahkan penggantian Hyperledger Fabric dengan Quorum, jaringan Ethereum pribadi lainnya (PoA atau bahkan PoW), secara signifikan mengurangi throughput nyata, namun pada saat yang sama mempertahankan UX normal (baik untuk pengguna di browser dan dari sisi sistem terintegrasi ). Saat mengganti Fabric dengan Ethereum dalam skema, hanya logika layanan percobaan ulang/dekorator yang perlu diubah dari menangani konflik MVCC menjadi kenaikan nonce atom dan pengiriman ulang. Buffer dan penyimpanan status memungkinkan untuk memisahkan waktu respons dari waktu pembentukan blok. Sekarang Anda dapat menambahkan ribuan node pesanan dan tidak takut blok terlalu sering terbentuk dan memuat layanan pemesanan.

Secara umum, hanya ini yang ingin saya bagikan. Saya akan senang jika itu membantu seseorang dalam pekerjaannya.

Sumber: www.habr.com

Tambah komentar