Pendaftaran Teragih untuk Set Roda: Pengalaman dengan Fabrik Hyperledger

Helo, saya bekerja dalam pasukan projek DRD KP (pendaftaran data teragih untuk memantau kitaran hayat set roda). Di sini saya ingin berkongsi pengalaman pasukan kami dalam membangunkan blockchain perusahaan untuk projek ini di bawah kekangan teknologi. Saya kebanyakannya akan bercakap tentang Fabrik Hyperledger, tetapi pendekatan yang diterangkan di sini boleh diekstrapolasi kepada mana-mana blok yang dibenarkan. Matlamat utama penyelidikan kami adalah untuk menyediakan penyelesaian blockchain perusahaan supaya produk akhir menyenangkan untuk digunakan dan tidak terlalu sukar untuk diselenggara.

Tidak akan ada penemuan, penyelesaian yang tidak dijangka dan tiada perkembangan unik akan diserlahkan di sini (kerana saya tidak mempunyai apa-apa). Saya hanya ingin berkongsi pengalaman sederhana saya, menunjukkan bahawa "itu mungkin" dan, mungkin, membaca tentang pengalaman orang lain dalam membuat keputusan yang baik dan tidak begitu baik dalam ulasan.

Masalah: Rantaian blok belum berskala

Hari ini, usaha ramai pembangun bertujuan untuk menjadikan blockchain sebagai teknologi yang benar-benar mudah, dan bukan bom jangka dalam pembungkus yang cantik. Saluran negeri, rollup optimistik, plasma dan sharding mungkin akan menjadi perkara biasa. Suatu hari nanti. Atau mungkin TON sekali lagi akan menangguhkan pelancaran selama enam bulan, dan Kumpulan Plasma seterusnya akan tidak lagi wujud. Kita boleh percaya pada peta jalan seterusnya dan membaca kertas putih yang cemerlang pada waktu malam, tetapi di sini dan sekarang kita perlu melakukan sesuatu dengan apa yang kita ada. Selesai.

Tugasan yang ditetapkan untuk pasukan kami dalam projek semasa kelihatan secara umum seperti ini: terdapat banyak subjek, mencapai beberapa ribu, yang tidak mahu membina hubungan atas kepercayaan; Ia adalah perlu untuk membina penyelesaian pada DLT yang akan berfungsi pada PC biasa tanpa keperluan prestasi khas dan memberikan pengalaman pengguna tidak lebih buruk daripada mana-mana sistem perakaunan berpusat. Teknologi di sebalik penyelesaian mesti meminimumkan kemungkinan manipulasi data yang berniat jahat - itulah sebabnya blockchain ada di sini.

Slogan daripada kertas putih dan media menjanjikan kami bahawa perkembangan seterusnya akan membolehkan kami membuat berjuta-juta transaksi sesaat. Apa sebenarnya?

Mainnet Ethereum kini berjalan pada ~30 tps. Kerana ini sahaja, sukar untuk menganggapnya sebagai blockchain dalam apa jua cara yang sesuai untuk keperluan korporat. Antara penyelesaian yang dibenarkan terdapat penanda aras yang menunjukkan 2000 tps (Kuorum) atau 3000 tps (Kain Hyperledger, terdapat sedikit kurang dalam penerbitan, tetapi anda perlu mengambil kira bahawa penanda aras telah dijalankan pada enjin konsensus lama). Adakah percubaan pemprosesan Fabrik radikal, yang tidak memberikan hasil yang paling teruk, 20000 tps, tetapi setakat ini ini hanya penyelidikan akademik, menunggu pelaksanaannya yang stabil. Tidak mungkin sebuah syarikat yang mampu untuk mengekalkan jabatan pemaju blockchain akan bersabar dengan penunjuk sedemikian. Tetapi masalahnya bukan sahaja throughput, terdapat juga latensi.

Latency

Kelewatan dari saat transaksi dimulakan hingga kelulusan terakhir oleh sistem bergantung bukan sahaja pada kelajuan mesej melalui semua peringkat pengesahan dan pesanan, tetapi juga pada parameter pembentukan blok. Walaupun blokchain kami membenarkan kami membuat komitmen pada kelajuan 1000000 tps, tetapi memerlukan 10 minit untuk menjana blok 488 MB, adakah ia akan menjadi lebih mudah untuk kami?

Mari kita lihat dengan lebih dekat kitaran hayat transaksi dalam Hyperledger Fabric untuk memahami di mana masa dibelanjakan dan bagaimana ia berkaitan dengan parameter penjanaan menyekat.

Pendaftaran Teragih untuk Set Roda: Pengalaman dengan Fabrik Hyperledger
diambil dari sini: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Pelanggan membuat transaksi, menghantarnya kepada rakan sebaya yang mengesahkan, yang terakhir mensimulasikan transaksi (menggunakan perubahan yang dibuat oleh kod rantaian kepada keadaan semasa, tetapi tidak komited kepada lejar) dan menerima RWSet - nama kunci, versi dan nilai ​​diambil daripada koleksi di CouchDB, (2) pengeendors menghantar semula RWSet yang ditandatangani kepada pelanggan, (3) pelanggan sama ada menyemak kehadiran tandatangan semua rakan sebaya yang diperlukan (endorser), dan kemudian menghantar transaksi ke perkhidmatan pesanan , atau menghantarnya tanpa pengesahan (semakan masih akan dilakukan kemudian), perkhidmatan pesanan membentuk satu blok dan ( 4) menghantar semula kepada semua rakan sebaya, bukan hanya pengendors; rakan sebaya menyemak bahawa versi utama dalam set baca sepadan dengan versi dalam pangkalan data, bahawa semua pengendors mempunyai tandatangan, dan akhirnya melakukan sekatan.

Tetapi bukan itu sahaja. Perkataan "pemesan membentuk blok" menyembunyikan bukan sahaja pesanan transaksi, tetapi juga 3 permintaan rangkaian berurutan dari ketua kepada pengikut dan belakang: pemimpin menambah mesej ke log, menghantarnya kepada pengikut, yang terakhir menambahnya ke log mereka, menghantar pengesahan replikasi yang berjaya kepada pemimpin, pemimpin melakukan mesej, menghantar pengesahan komit kepada pengikut, pengikut melakukan. Lebih kecil saiz dan masa pembentukan blok, lebih kerap perkhidmatan pesanan perlu mewujudkan konsensus. Hyperledger Fabric mempunyai dua parameter untuk pembentukan blok: BatchTimeout - masa pembentukan blok dan BatchSize - saiz blok (bilangan transaksi dan saiz blok itu sendiri dalam bait). Sebaik sahaja salah satu parameter mencapai had, blok baharu dikeluarkan. Lebih banyak nod pesanan, lebih lama masa yang diperlukan. Oleh itu, anda perlu meningkatkan BatchTimeout dan BatchSize. Tetapi oleh kerana RWSets adalah versi, lebih besar blok yang kami buat, lebih tinggi kemungkinan konflik MVCC. Di samping itu, apabila BatchTimeout meningkat, UX merosot secara besar-besaran. Skim berikut untuk menyelesaikan masalah ini nampaknya munasabah dan jelas kepada saya.

Bagaimana untuk mengelakkan menunggu pemuktamadkan blok dan tidak kehilangan keupayaan untuk menjejak status transaksi

Semakin lama masa pembentukan dan saiz blok, semakin tinggi daya pengeluaran blok tersebut. Satu tidak mengikuti secara langsung dari yang lain, tetapi harus diingat bahawa mewujudkan konsensus dalam RAFT memerlukan tiga permintaan rangkaian daripada pemimpin kepada pengikut dan belakang. Lebih banyak nod pesanan, lebih lama masa yang diperlukan. Lebih kecil saiz dan masa pembentukan blok, lebih banyak interaksi sedemikian wujud. Bagaimana untuk meningkatkan masa penjanaan dan saiz blok tanpa meningkatkan masa tindak balas sistem untuk pengguna akhir?

Pertama, kami perlu menyelesaikan konflik MVCC yang disebabkan oleh saiz blok yang besar, yang mungkin termasuk RWSets berbeza dengan versi yang sama. Jelas sekali, di sisi pelanggan (berkaitan dengan rangkaian blockchain, ini mungkin bahagian belakang, dan saya maksudkan itu) yang anda perlukan Pengendali konflik MVCC, yang boleh menjadi sama ada perkhidmatan berasingan atau penghias biasa di atas panggilan yang memulakan transaksi dengan cuba semula logik.

Cuba semula boleh dilaksanakan dengan strategi eksponen, tetapi kemudian kependaman akan merosot secara eksponen. Oleh itu, anda harus menggunakan sama ada percubaan semula rawak dalam had kecil tertentu, atau yang berterusan. Dengan melihat kemungkinan perlanggaran dalam pilihan pertama.

Langkah seterusnya ialah menjadikan interaksi pelanggan dengan sistem tidak segerak supaya ia tidak menunggu selama 15, 30 atau 10000000 saat, yang akan kami tetapkan sebagai BatchTimeout. Tetapi pada masa yang sama, adalah perlu untuk mengekalkan keupayaan untuk mengesahkan bahawa perubahan yang dimulakan oleh transaksi adalah/tidak direkodkan dalam blockchain.
Pangkalan data boleh digunakan untuk menyimpan status transaksi. Pilihan paling mudah ialah CouchDB kerana kemudahan penggunaannya: pangkalan data mempunyai UI di luar kotak, API REST, dan anda boleh menyediakan replikasi dan sharding untuknya dengan mudah. Anda hanya boleh membuat koleksi berasingan dalam contoh CouchDB yang sama yang menggunakan Fabric untuk menyimpan keadaan dunianya. Kita perlu menyimpan jenis dokumen ini.

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

Dokumen ini ditulis ke pangkalan data sebelum transaksi dihantar kepada rakan sebaya, ID entiti dikembalikan kepada pengguna (ID yang sama digunakan sebagai kunci) jika ini adalah operasi penciptaan, dan kemudian medan Status, TxID dan Ralat adalah dikemas kini apabila maklumat berkaitan diterima daripada rakan sebaya.

Pendaftaran Teragih untuk Set Roda: Pengalaman dengan Fabrik Hyperledger

Dalam skim ini, pengguna tidak menunggu sehingga blok akhirnya terbentuk, menonton roda berputar pada skrin selama 10 saat, dia menerima respons segera daripada sistem dan terus bekerja.

Kami memilih BoltDB untuk menyimpan status transaksi kerana kami perlu menjimatkan memori dan tidak mahu membuang masa pada interaksi rangkaian dengan pelayan pangkalan data yang berasingan, terutamanya apabila interaksi ini berlaku menggunakan protokol teks biasa. Ngomong-ngomong, sama ada anda menggunakan CouchDB untuk melaksanakan skema yang diterangkan di atas atau hanya untuk menyimpan keadaan dunia, dalam apa jua keadaan adalah wajar untuk mengoptimumkan cara data disimpan dalam CouchDB. Secara lalai, dalam CouchDB, saiz nod b-tree ialah 1279 bait, yang jauh lebih kecil daripada saiz sektor pada cakera, yang bermaksud kedua-dua membaca dan mengimbangi semula pokok akan memerlukan lebih banyak akses fizikal kepada cakera. Saiz optimum sepadan dengan standard Format Lanjutan dan ialah 4 kilobait. Untuk mengoptimumkan kita perlu menetapkan parameter btree_chunk_size sama dengan 4096 dalam fail konfigurasi CouchDB. Bagi BoltDB campur tangan manual sedemikian tidak diperlukan.

Tekanan belakang: strategi penampan

Tetapi mungkin terdapat banyak mesej. Lebih daripada yang boleh dikendalikan oleh sistem, berkongsi sumber dengan sedozen perkhidmatan lain selain yang ditunjukkan dalam rajah - dan semua ini harus berfungsi dengan sempurna walaupun pada mesin yang menjalankan Intellij Idea akan menjadi sangat membosankan.

Masalah kapasiti berbeza sistem komunikasi, pengeluar dan pengguna, diselesaikan dengan cara yang berbeza. Mari lihat apa yang boleh kita lakukan.

Menurun: Kami boleh mendakwa bahawa kami mampu memproses paling banyak transaksi X dalam T saat. Semua permintaan yang melebihi had ini dibuang. Ini agak mudah, tetapi kemudian anda boleh melupakan UX.

Mengawal: pengguna mesti mempunyai beberapa jenis antara muka yang melaluinya, bergantung pada beban, dia boleh mengawal TPS pengeluar. Tidak buruk, tetapi ia mengenakan kewajipan kepada pemaju pelanggan yang membuat beban untuk melaksanakan antara muka ini. Ini tidak boleh diterima untuk kami, kerana blokchain pada masa hadapan akan disepadukan ke dalam sejumlah besar sistem yang telah lama wujud.

Buffering: Daripada cuba menahan aliran data input, kami boleh menampan aliran ini dan memprosesnya pada kelajuan yang diperlukan. Jelas sekali ini adalah penyelesaian terbaik jika kami ingin memberikan pengalaman pengguna yang baik. Kami melaksanakan penimbal menggunakan baris gilir dalam RabbitMQ.

Pendaftaran Teragih untuk Set Roda: Pengalaman dengan Fabrik Hyperledger

Dua tindakan baharu telah ditambahkan pada skema: (1) selepas permintaan kepada API tiba, mesej dengan parameter yang diperlukan untuk memanggil transaksi diletakkan dalam baris gilir, dan pelanggan menerima mesej bahawa transaksi telah diterima oleh sistem, (2) bahagian belakang membaca data pada kelajuan yang dinyatakan dalam konfigurasi daripada baris gilir; memulakan transaksi dan mengemas kini data dalam stor status.
Kini anda boleh meningkatkan masa pembentukan dan kapasiti blok seberapa banyak yang anda mahu, menyembunyikan kelewatan daripada pengguna.

Alat lain

Tiada apa-apa yang dikatakan di sini tentang kod rantai, kerana, sebagai peraturan, tiada apa-apa untuk dioptimumkan di dalamnya. Kod rantai hendaklah semudah dan selamat yang mungkin - itu sahaja yang diperlukan daripadanya. Rangka kerja membantu kami menulis kod rantai dengan mudah dan selamat CCKit daripada S7 Techlab dan penganalisis statik menghidupkan semula^CC.

Selain itu, pasukan kami sedang membangunkan satu set utiliti untuk menjadikan kerja dengan Fabric mudah dan menyeronokkan: penjelajah blockchain, utiliti untuk perubahan konfigurasi rangkaian automatik (menambah/mengalih keluar organisasi, nod RAFT), utiliti untuk pembatalan sijil dan penyingkiran identiti. Jika anda ingin menyumbang, anda dialu-alukan.

Kesimpulan

Pendekatan ini membolehkan anda dengan mudah menggantikan Hyperledger Fabric dengan Quorum, rangkaian Ethereum peribadi lain (PoA atau bahkan PoW), dengan ketara mengurangkan daya pengeluaran sebenar, tetapi pada masa yang sama mengekalkan UX biasa (kedua-duanya untuk pengguna dalam penyemak imbas dan untuk sistem bersepadu). Apabila menggantikan Fabric dengan Ethereum dalam skema, anda hanya perlu menukar logik perkhidmatan cuba semula/penghias daripada memproses konflik MVCC kepada penambahan dan penghantaran semula nonce atom. Penimbalan dan storan status memungkinkan untuk memisahkan masa tindak balas daripada masa pembentukan blok. Kini anda boleh menambah beribu-ribu nod pesanan dan tidak takut bahawa blok dibentuk terlalu kerap dan memuatkan perkhidmatan pesanan.

Pada asasnya, itu sahaja yang saya ingin kongsikan. Saya akan gembira jika ini membantu seseorang dalam kerja mereka.

Sumber: www.habr.com

Tambah komen