Ibinahagi na Registry para sa Mga Wheelset: Isang Karanasan sa Hyperledger Fabric

Kumusta, nagtatrabaho ako sa pangkat ng proyekto ng DRD KP (naipamahagi ang pagpapatala ng data para sa pagsubaybay sa ikot ng buhay ng mga hanay ng gulong). Dito gusto kong ibahagi ang karanasan ng aming koponan sa pagbuo ng isang enterprise blockchain para sa proyektong ito sa ilalim ng mga hadlang ng teknolohiya. Karamihan ay pag-uusapan ko ang tungkol sa Hyperledger Fabric, ngunit ang diskarte na inilarawan dito ay maaaring i-extrapolated sa anumang pinahihintulutang blockchain. Ang pinakalayunin ng aming pananaliksik ay ang maghanda ng mga solusyon sa enterprise blockchain upang ang huling produkto ay kaaya-aya gamitin at hindi masyadong mahirap pangalagaan.

Walang mga pagtuklas, mga hindi inaasahang solusyon, at walang mga kakaibang pag-unlad na mai-highlight dito (dahil wala akong anumang). Gusto ko lang ibahagi ang aking katamtamang karanasan, ipakita na "posible" at, marahil, basahin ang tungkol sa mga karanasan ng ibang tao sa paggawa ng mabuti at hindi napakahusay na mga desisyon sa mga komento.

Problema: Hindi pa nasusukat ang mga Blockchain

Ngayon, ang mga pagsisikap ng maraming mga developer ay naglalayong gawing isang tunay na maginhawang teknolohiya ang blockchain, at hindi isang bombang oras sa isang magandang wrapper. Ang mga channel ng estado, optimistic rollup, plasma at sharding ay malamang na maging karaniwan. Ilang araw. O marahil ay muling ipagpaliban ng TON ang paglulunsad sa loob ng anim na buwan, at ang susunod na Plasma Group ay hindi na umiral. Maaari tayong maniwala sa susunod na roadmap at magbasa ng mga makikinang na puting papel sa gabi, ngunit narito at ngayon kailangan nating gumawa ng isang bagay sa kung ano ang mayroon tayo. Gawin ang tae.

Ang gawaing itinakda para sa aming koponan sa kasalukuyang proyekto ay ganito ang hitsura sa pangkalahatan: maraming mga paksa, na umaabot sa ilang libo, na hindi gustong bumuo ng mga relasyon sa tiwala; Ito ay kinakailangan upang bumuo ng isang solusyon sa DLT na gagana sa mga ordinaryong PC na walang mga espesyal na kinakailangan sa pagganap at magbigay ng isang karanasan ng gumagamit na hindi mas masahol pa kaysa sa anumang mga sentralisadong sistema ng accounting. Ang teknolohiya sa likod ng solusyon ay dapat mabawasan ang posibilidad ng malisyosong pagmamanipula ng data - kaya't narito ang blockchain.

Ang mga slogan mula sa mga whitepaper at media ay nangangako sa amin na ang susunod na pag-unlad ay magbibigay-daan sa amin na gumawa ng milyun-milyong transaksyon sa bawat segundo. Ano ba talaga?

Ang Mainnet Ethereum ay kasalukuyang tumatakbo sa ~30 tps. Dahil dito lamang, mahirap isipin ito bilang blockchain sa anumang paraan na angkop para sa mga pangangailangan ng korporasyon. Kabilang sa mga pinahintulutang solusyon ay mayroong mga benchmark na nagpapakita ng 2000 tps (Korum) o 3000 tps (Hyperledger Fabric, mayroong isang maliit na mas kaunti sa publikasyon, ngunit kailangan mong isaalang-alang na ang benchmark ay isinagawa sa lumang consensus engine). ay isang pagtatangka sa radikal na pagproseso ng Tela, na hindi nagbigay ng pinakamasamang resulta, 20000 tps, ngunit sa ngayon ito ay akademikong pananaliksik lamang, naghihintay para sa matatag na pagpapatupad nito. Hindi malamang na ang isang korporasyon na kayang magpanatili ng isang departamento ng mga developer ng blockchain ay magtitiis sa mga naturang indicator. Ngunit ang problema ay hindi lamang throughput, mayroon ding latency.

Latency

Ang pagkaantala mula sa sandaling ang isang transaksyon ay sinimulan hanggang sa huling pag-apruba ng system ay nakasalalay hindi lamang sa bilis kung saan ang mensahe ay dumaan sa lahat ng mga yugto ng pagpapatunay at pag-order, kundi pati na rin sa mga parameter ng pagbuo ng bloke. Kahit na pinapayagan tayo ng ating blockchain na mag-commit sa bilis na 1000000 tps, ngunit nangangailangan ng 10 minuto upang makabuo ng 488 MB block, magiging mas madali ba ito para sa atin?

Tingnan natin ang lifecycle ng transaksyon sa Hyperledger Fabric upang maunawaan kung saan ginugugol ang oras at kung paano ito nauugnay sa pag-block ng mga parameter ng henerasyon.

Ibinahagi na Registry para sa Mga Wheelset: Isang Karanasan sa Hyperledger Fabric
kinuha mula dito: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Lumilikha ang kliyente ng isang transaksyon, ipinapadala ito sa pag-eendorso ng mga kapantay, ang huli ay gayahin ang transaksyon (ilapat ang mga pagbabagong ginawa ng chaincode sa kasalukuyang estado, ngunit huwag mag-commit sa ledger) at tumanggap ng RWSet - mga pangunahing pangalan, bersyon at halaga ​​na kinuha mula sa koleksyon sa CouchDB, ( 2) nagpapadala ang mga endorser ng nilagdaang RWSet sa kliyente, (3) sinusuri ng kliyente ang pagkakaroon ng mga pirma ng lahat ng kinakailangang peer (endorser), at pagkatapos ay ipinapadala ang transaksyon sa serbisyo ng pag-order , o ipapadala ito nang walang pag-verify (ang tseke ay magaganap pa rin sa ibang pagkakataon), ang serbisyo sa pag-order ay bumubuo ng isang bloke at ( 4) ibinabalik sa lahat ng mga kapantay, hindi lamang sa mga nag-eendorso; tinitingnan ng mga kasamahan na ang mga pangunahing bersyon sa read set ay tumutugma sa mga bersyon sa database, na ang lahat ng mga nag-endorso ay may mga lagda, at sa wakas ay ginawa ang block.

Ngunit hindi lang iyon. Ang mga salitang "nag-order ay bumubuo ng isang bloke" ay nagtatago hindi lamang sa pag-order ng mga transaksyon, kundi pati na rin ng 3 sunud-sunod na mga kahilingan sa network mula sa pinuno hanggang sa mga tagasunod at pabalik: ang pinuno ay nagdaragdag ng isang mensahe sa log, ipinapadala ito sa mga tagasunod, ang huli ay idinagdag ito. sa kanilang log, nagpapadala ng kumpirmasyon ng matagumpay na pagtitiklop sa pinuno, ang pinuno ay nag-commit ng mensahe , nagpapadala ng commit confirmation sa mga tagasunod, ang mga tagasunod ay nag-commit. Kung mas maliit ang laki at oras ng pagbuo ng bloke, mas madalas na kailangang magtatag ng consensus ang serbisyo sa pag-order. Ang Hyperledger Fabric ay may dalawang parameter para sa pagbuo ng block: BatchTimeout - oras ng pagbuo ng block at BatchSize - laki ng block (ang bilang ng mga transaksyon at ang laki ng block mismo sa mga byte). Sa sandaling maabot ng isa sa mga parameter ang limitasyon, isang bagong bloke ang ilalabas. Kung mas maraming mga node ng order, mas matagal ito. Samakatuwid, kailangan mong dagdagan ang BatchTimeout at BatchSize. Ngunit dahil may bersyon ang RWSets, mas malaki ang block na ginagawa namin, mas mataas ang posibilidad ng mga salungatan sa MVCC. Bilang karagdagan, habang tumataas ang BatchTimeout, ang UX ay sakuna na bumababa. Ang sumusunod na pamamaraan para sa paglutas ng mga problemang ito ay tila makatwiran at halata sa akin.

Paano maiwasan ang paghihintay para sa block finalization at hindi mawalan ng kakayahang subaybayan ang katayuan ng transaksyon

Kung mas mahaba ang oras ng pagbuo at laki ng block, mas mataas ang throughput ng blockchain. Ang isa ay hindi direktang sumusunod sa isa, ngunit dapat tandaan na ang pagtatatag ng pinagkasunduan sa RAFT ay nangangailangan ng tatlong kahilingan sa network mula sa pinuno hanggang sa mga tagasunod at pabalik. Kung mas maraming mga node ng order, mas matagal ito. Kung mas maliit ang laki at oras ng pagbuo ng bloke, mas maraming ganoong pakikipag-ugnayan ang naroroon. Paano dagdagan ang oras ng pagbuo at laki ng bloke nang hindi dinadagdagan ang oras ng pagtugon ng system para sa end user?

Una, kailangan nating lutasin ang mga salungatan sa MVCC na dulot ng malaking sukat ng block, na maaaring magsama ng iba't ibang RWSets na may parehong bersyon. Malinaw, sa panig ng kliyente (kaugnay ng network ng blockchain, maaaring ito ang backend, at ibig kong sabihin) kailangan mo MVCC conflict handler, na maaaring maging isang hiwalay na serbisyo o isang regular na dekorador sa itaas ng tawag na nagpapasimula ng transaksyon gamit ang retry logic.

Maaaring ipatupad ang muling pagsubok gamit ang isang exponential na diskarte, ngunit pagkatapos ay ang latency ay bababa nang kasing bilis. Kaya dapat mong gamitin ang alinman sa isang randomized na muling pagsubok sa loob ng ilang maliliit na limitasyon, o isang pare-pareho. Sa isang mata sa mga posibleng banggaan sa unang opsyon.

Ang susunod na hakbang ay gawing asynchronous ang pakikipag-ugnayan ng kliyente sa system upang hindi ito maghintay ng 15, 30 o 10000000 segundo, na itatakda namin bilang BatchTimeout. Ngunit sa parehong oras, ito ay kinakailangan upang mapanatili ang kakayahang i-verify na ang mga pagbabago na pinasimulan ng transaksyon ay/ay hindi naitala sa blockchain.
Ang isang database ay maaaring gamitin upang mag-imbak ng katayuan ng transaksyon. Ang pinakasimpleng opsyon ay ang CouchDB dahil sa kadalian ng paggamit nito: ang database ay may UI out of the box, isang REST API, at madali mong mai-set up ang replication at sharding para dito. Maaari ka lang gumawa ng hiwalay na koleksyon sa parehong halimbawa ng CouchDB na gumagamit ng Fabric upang iimbak ang estado nito sa mundo. Kailangan nating mag-imbak ng mga ganitong uri ng mga dokumento.

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

Ang dokumentong ito ay isinulat sa database bago ipadala ang transaksyon sa mga kapantay, ang entity ID ay ibinalik sa user (ang parehong ID ay ginagamit bilang isang susi) kung ito ay isang operasyon ng paglikha, at pagkatapos ay ang Status, TxID at Error na mga patlang ay na-update habang natatanggap ang may-katuturang impormasyon mula sa mga kapantay.

Ibinahagi na Registry para sa Mga Wheelset: Isang Karanasan sa Hyperledger Fabric

Sa pamamaraang ito, ang gumagamit ay hindi naghihintay para sa block na sa wakas ay mabuo, pinapanood ang umiikot na gulong sa screen sa loob ng 10 segundo, nakatanggap siya ng agarang tugon mula sa system at patuloy na gumagana.

Pinili namin ang BoltDB upang mag-imbak ng mga katayuan ng transaksyon dahil kailangan naming mag-save ng memorya at ayaw naming mag-aksaya ng oras sa pakikipag-ugnayan sa network sa isang hiwalay na server ng database, lalo na kapag nangyari ang pakikipag-ugnayan na ito gamit ang isang plain text protocol. Sa pamamagitan ng paraan, kung gagamitin mo ang CouchDB upang ipatupad ang scheme na inilarawan sa itaas o para lamang mag-imbak ng estado ng mundo, sa anumang kaso ay makatuwirang i-optimize ang paraan ng pag-imbak ng data sa CouchDB. Bilang default, sa CouchDB, ang laki ng mga b-tree node ay 1279 bytes, na mas maliit kaysa sa laki ng sektor sa disk, na nangangahulugan na ang parehong pagbabasa at muling pagbabalanse ng puno ay mangangailangan ng higit pang pisikal na pag-access sa disk. Ang pinakamainam na sukat ay tumutugma sa pamantayan Advanced na Format at 4 kilobytes. Upang ma-optimize kailangan naming itakda ang parameter btree_chunk_size na katumbas ng 4096 sa file ng pagsasaayos ng CouchDB. Para sa BoltDB tulad ng manu-manong interbensyon hindi kinakailangan.

Backpressure: diskarte sa buffer

Ngunit maaaring mayroong maraming mga mensahe. Higit pa sa kayang hawakan ng system, ang pagbabahagi ng mga mapagkukunan sa isang dosenang iba pang mga serbisyo bukod sa mga ipinapakita sa diagram - at lahat ng ito ay dapat gumana nang walang kamali-mali kahit na sa mga makina kung saan ang pagpapatakbo ng Intellij Idea ay lubhang nakakapagod.

Ang problema ng iba't ibang mga kapasidad ng mga sistema ng komunikasyon, producer at consumer, ay nalutas sa iba't ibang paraan. Tingnan natin kung ano ang magagawa natin.

Pag-drop: Maaari naming i-claim na kaya naming iproseso ang pinakamaraming X na transaksyon sa T segundo. Ang lahat ng kahilingang lumampas sa limitasyong ito ay itatapon. Ito ay medyo simple, ngunit pagkatapos ay maaari mong kalimutan ang tungkol sa UX.

Pagkontrol: ang mamimili ay dapat magkaroon ng ilang uri ng interface kung saan, depende sa load, makokontrol niya ang TPS ng producer. Hindi masama, ngunit nagpapataw ito ng mga obligasyon sa mga developer ng kliyente na lumilikha ng load upang ipatupad ang interface na ito. Ito ay hindi katanggap-tanggap para sa amin, dahil ang blockchain ay sa hinaharap ay isasama sa isang malaking bilang ng mga matagal nang umiiral na mga sistema.

Buffering: Sa halip na subukang pigilan ang stream ng input ng data, maaari naming i-buffer ang stream na ito at iproseso ito sa kinakailangang bilis. Malinaw na ito ang pinakamahusay na solusyon kung gusto naming magbigay ng magandang karanasan ng user. Ipinatupad namin ang buffer gamit ang isang queue sa RabbitMQ.

Ibinahagi na Registry para sa Mga Wheelset: Isang Karanasan sa Hyperledger Fabric

Dalawang bagong aksyon ang idinagdag sa scheme: (1) pagkatapos dumating ang isang kahilingan sa API, isang mensahe na may mga parameter na kinakailangan upang tumawag sa isang transaksyon ay inilagay sa pila, at ang kliyente ay makakatanggap ng mensahe na ang transaksyon ay tinanggap ng ang system, (2) binabasa ng backend ang data sa bilis na tinukoy sa config mula sa pila; nagpapasimula ng transaksyon at nag-a-update ng data sa status store.
Ngayon ay maaari mong dagdagan ang oras ng pagbuo at i-block ang kapasidad hangga't gusto mo, na nagtatago ng mga pagkaantala mula sa user.

Iba pang mga kasangkapan

Walang sinabi dito tungkol sa chaincode, dahil, bilang panuntunan, walang i-optimize dito. Ang Chaincode ay dapat na simple at secure hangga't maaari - iyon lang ang kinakailangan dito. Tinutulungan kami ng framework na magsulat ng chaincode nang simple at ligtas CCKit mula sa S7 Techlab at static analyzer buhayin^CC.

Bilang karagdagan, ang aming koponan ay bumubuo ng isang hanay ng mga kagamitan upang gawing simple at kasiya-siya ang pagtatrabaho sa Fabric: blockchain explorer, isang utility para sa awtomatikong pagbabago sa configuration ng network (pagdaragdag/pag-alis ng mga organisasyon, mga RAFT node), utility para sa pagbawi ng mga sertipiko at pagtanggal ng pagkakakilanlan. Kung gusto mong mag-ambag, welcome ka.

Konklusyon

Ang diskarte na ito ay nagbibigay-daan sa iyo upang madaling palitan ang Hyperledger Fabric sa Quorum, iba pang mga pribadong Ethereum network (PoA o kahit PoW), makabuluhang bawasan ang aktwal na throughput, ngunit sa parehong oras mapanatili ang normal na UX (parehong para sa mga gumagamit sa browser at para sa mga pinagsama-samang system). Kapag pinapalitan ang Fabric ng Ethereum sa scheme, kakailanganin mo lang baguhin ang logic ng retry service/decorator mula sa pagpoproseso ng MVCC conflicts sa atomic nonce increment at resending. Dahil sa buffering at imbakan ng katayuan, naging posible na ihiwalay ang oras ng pagtugon mula sa oras ng pagbuo ng bloke. Ngayon ay maaari kang magdagdag ng libu-libong mga node ng order at huwag matakot na ang mga bloke ay madalas na nabuo at i-load ang serbisyo sa pag-order.

Basically, yun lang ang gusto kong ibahagi. Matutuwa ako kung makakatulong ito sa isang tao sa kanilang trabaho.

Pinagmulan: www.habr.com

Magdagdag ng komento