Verspreide register vir wielestelle: 'n ervaring met Hyperledger Fabric

Hallo, ek werk in die span van die DRD KP-projek (verspreide dataregister vir die monitering van die lewensiklus van wielstelle). Hier wil ek ons ​​span se ervaring deel in die ontwikkeling van 'n ondernemingsblokketting vir hierdie projek onder die beperkings van tegnologie. Ek sal meestal praat oor die Hyperledger Fabric, maar die benadering wat hier beskryf word, kan geëkstrapoleer word na enige gemagtigde blokketting. Die uiteindelike doel van ons navorsing is om ondernemingsblokkettingoplossings voor te berei sodat die finale produk aangenaam is om te gebruik en nie te moeilik om te onderhou nie.

Daar sal geen ontdekkings, onverwagte oplossings wees nie, en geen unieke ontwikkelings sal hier uitgelig word nie (want ek het nie enige nie). Ek wil net my beskeie ervaring deel, wys dat "dit moontlik was" en miskien lees oor ander mense se ervarings van goeie en nie so goeie besluite nie in die kommentaar.

Probleem: Blockchains skaal nog nie

Vandag is die pogings van baie ontwikkelaars daarop gemik om blockchain 'n werklik gerieflike tegnologie te maak, en nie 'n tydbom in 'n pragtige omhulsel nie. Staatskanale, optimistiese oprol, plasma en versplintering sal waarskynlik alledaags word. Een of ander dag. Of dalk sal TON weer die bekendstelling vir ses maande uitstel, en die volgende Plasma Groep sal ophou bestaan. Ons kan glo in die volgende padkaart en saans briljante witskrifte lees, maar hier en nou moet ons iets doen met wat ons het. Maak kak klaar.

Die taak wat vir ons span in die huidige projek gestel is, lyk oor die algemeen so: daar is baie vakke, wat etlike duisende bereik, wat nie verhoudings op vertroue wil bou nie; Dit is nodig om 'n oplossing op DLT te bou wat op gewone rekenaars sal werk sonder spesiale prestasievereistes en 'n gebruikerservaring bied wat nie erger is as enige gesentraliseerde rekeningkundige stelsels nie. Die tegnologie agter die oplossing moet die moontlikheid van kwaadwillige manipulasie van data tot die minimum beperk – dis hoekom blockchain hier is.

Slagspreuke van witskrifte en die media belowe ons dat die volgende ontwikkeling ons in staat sal stel om miljoene transaksies per sekonde te maak. Wat is dit regtig?

Mainnet Ethereum loop tans teen ~30 tps. As gevolg hiervan alleen, is dit moeilik om dit as blokketting te beskou op enige manier wat geskik is vir korporatiewe behoeftes. Onder toegestane oplossings is daar maatstawwe wat 2000 tps toon (kworum) of 3000 tps (Hyperledger Fabric, daar is 'n bietjie minder in die publikasie, maar jy moet in ag neem dat die maatstaf op die ou konsensus-enjin uitgevoer is). Was 'n poging tot radikale Stofverwerking, wat nie die ergste resultate gegee het nie, 20000 XNUMX tps, maar tot dusver is dit net akademiese navorsing wat wag vir die stabiele implementering daarvan. Dit is onwaarskynlik dat 'n korporasie wat dit kan bekostig om 'n departement van blockchain-ontwikkelaars te onderhou, sulke aanwysers sal verdra. Maar die probleem is nie net deurset nie, daar is ook latensie.

latency

Die vertraging vanaf die oomblik dat 'n transaksie geïnisieer word tot die finale goedkeuring daarvan deur die stelsel hang nie net af van die spoed waarteen die boodskap deur alle stadiums van validering en bestelling gaan nie, maar ook van die blokvormingsparameters. Selfs as ons blokketting ons toelaat om teen 'n spoed van 1000000 10 488 tps te verbind, maar XNUMX minute benodig om 'n XNUMX MB-blok te genereer, sal dit vir ons makliker word?

Kom ons kyk van naderby na die transaksielewensiklus in Hyperledger Fabric om te verstaan ​​waar tyd spandeer word en hoe dit verband hou met blokgenereringsparameters.

Verspreide register vir wielestelle: 'n ervaring met Hyperledger Fabric
van hier af geneem: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Die kliënt skep 'n transaksie, stuur dit na onderskryf eweknieë, laasgenoemde simuleer die transaksie (pas veranderinge wat deur kettingkode gemaak is op die huidige toestand, maar verbind nie tot die grootboek nie) en ontvang RWSet - sleutelname, weergawes en waardes ​​ geneem uit die versameling in CouchDB, ( 2) endosseerders stuur 'n getekende RWSet terug aan die kliënt, (3) die kliënt kyk óf vir die teenwoordigheid van handtekeninge van alle nodige eweknieë (endosseerders), en stuur dan die transaksie na die besteldiens , of stuur dit sonder verifikasie (die kontrolering sal steeds later plaasvind), vorm die besteldiens 'n blok en ( 4) stuur terug na alle eweknieë, nie net endosseerders nie; eweknieë kontroleer dat die sleutelweergawes in die leesstel ooreenstem met die weergawes in die databasis, dat alle endosseerders handtekeninge het, en pleeg uiteindelik die blok.

Maar dit is nie al nie. Die woorde "besteller vorm 'n blok" verberg nie net die bestelling van transaksies nie, maar ook 3 opeenvolgende netwerkversoeke van die leier na die volgelinge en terug: die leier voeg 'n boodskap by die logboek, stuur dit aan die volgelinge, laasgenoemde voeg dit by na hul log, stuur bevestiging van suksesvolle replikasie aan die leier, die leier pleeg die boodskap, stuur commit bevestiging aan volgelinge, volgers commit. Hoe kleiner die grootte en tyd van blokvorming, hoe meer dikwels sal die besteldiens konsensus moet vestig. Hyperledger Fabric het twee parameters vir blokvorming: BatchTimeout - blokvormingstyd en BatchSize - blokgrootte (die aantal transaksies en die grootte van die blok self in grepe). Sodra een van die parameters die limiet bereik, word 'n nuwe blok vrygestel. Hoe meer bestellingsnodes, hoe langer sal dit neem. Daarom moet u BatchTimeout en BatchSize verhoog. Maar aangesien RWSets weergawes is, hoe groter die blok wat ons maak, hoe groter is die waarskynlikheid van MVCC-konflikte. Daarbenewens, soos BatchTimeout toeneem, verswak die UX katastrofies. Die volgende skema vir die oplossing van hierdie probleme lyk vir my redelik en voor die hand liggend.

Hoe om te vermy om te wag vir blokfinalisering en nie die vermoë om transaksiestatus op te spoor verloor nie

Hoe langer die vormingstyd en blokgrootte, hoe hoër is die deurset van die blokketting. Die een volg nie direk op die ander nie, maar daar moet onthou word dat die vestiging van konsensus in RAFT drie netwerkversoeke van die leier na die volgelinge en terug vereis. Hoe meer bestellingsnodes, hoe langer sal dit neem. Hoe kleiner die grootte en tyd van blokvorming, hoe meer sulke interaksies is daar. Hoe om die generasietyd en blokgrootte te verhoog sonder om die stelselreaksietyd vir die eindgebruiker te verhoog?

Eerstens moet ons op een of ander manier MVCC-konflikte oplos wat veroorsaak word deur 'n groot blokgrootte, wat verskillende RWSets met dieselfde weergawe kan insluit. Natuurlik, aan die kliëntkant (met betrekking tot die blockchain-netwerk, kan dit die backend wees, en ek bedoel dit) wat jy nodig het MVCC konflik hanteerder, wat óf 'n aparte diens óf 'n gereelde versierder bokant die oproep kan wees wat die transaksie met herprobeerlogika inisieer.

Herprobeer kan met 'n eksponensiële strategie geïmplementeer word, maar dan sal latensie net so eksponensieel afneem. So jy moet óf 'n ewekansige herprobeer binne sekere klein perke, óf 'n konstante een gebruik. Met die oog op moontlike botsings in die eerste opsie.

Die volgende stap is om die kliënt se interaksie met die stelsel asinchroon te maak sodat dit nie vir 15, 30 of 10000000 sekondes wag nie, wat ons as BatchTimeout sal stel. Maar terselfdertyd is dit nodig om die vermoë te handhaaf om te verifieer dat die veranderinge wat deur die transaksie geïnisieer word, in die blokketting aangeteken is/nie.
'n Databasis kan gebruik word om transaksiestatus te stoor. Die eenvoudigste opsie is CouchDB as gevolg van die gebruiksgemak: die databasis het 'n UI uit die boks, 'n REST API, en jy kan maklik replikasie en sharding daarvoor opstel. U kan eenvoudig 'n aparte versameling skep in dieselfde CouchDB-instansie wat Fabric gebruik om sy wêreldtoestand te stoor. Ons moet hierdie tipe dokumente stoor.

{
 Status string // Статус транзакции: "pending", "done", "failed"
 TxID: string // ID транзакции
 Error: string // optional, сообщение об ошибке
}

Hierdie dokument word na die databasis geskryf voordat die transaksie aan eweknieë gestuur word, die entiteit-ID word aan die gebruiker teruggestuur (dieselfde ID word as 'n sleutel gebruik) as dit 'n skeppingshandeling is, en dan is die Status-, TxID- en Error-velde opgedateer soos relevante inligting van eweknieë ontvang word.

Verspreide register vir wielestelle: 'n ervaring met Hyperledger Fabric

In hierdie skema wag die gebruiker nie vir die blok om uiteindelik te vorm nie, kyk na die draaiwiel op die skerm vir 10 sekondes, hy ontvang 'n onmiddellike reaksie van die stelsel en gaan voort om te werk.

Ons het BoltDB gekies om transaksiestatusse te stoor omdat ons geheue moet bespaar en nie tyd wil mors op netwerkinteraksie met 'n aparte databasisbediener nie, veral wanneer hierdie interaksie met 'n gewone teksprotokol plaasvind. Terloops, of jy CouchDB gebruik om die skema hierbo beskryf te implementeer of bloot om wêreldtoestand te stoor, dit maak in elk geval sin om die manier waarop data in CouchDB gestoor word, te optimaliseer. By verstek, in CouchDB, is die grootte van b-boom nodusse 1279 grepe, wat baie kleiner is as die sektorgrootte op die skyf, wat beteken dat beide die lees en herbalansering van die boom meer fisiese toegang tot die skyf sal vereis. Die optimale grootte stem ooreen met die standaard Gevorderde formaat en is 4 kilogrepe. Om te optimaliseer, moet ons die parameter stel btree_chunk_size gelyk aan 4096 in die CouchDB-konfigurasielêer. Vir BoltDB sulke handmatige ingryping nie nodig nie.

Terugdruk: bufferstrategie

Maar daar kan baie boodskappe wees. Meer as wat die stelsel kan hanteer, deel hulpbronne met 'n dosyn ander dienste behalwe dié wat in die diagram gewys word - en dit alles behoort foutloos te werk, selfs op masjiene waarop Intellij Idea uiters vervelig sou wees.

Die probleem van verskillende kapasiteit van kommunikasiestelsels, produsent en verbruiker, word op verskillende maniere opgelos. Kom ons kyk wat ons kan doen.

weglating: Ons kan beweer dat ons in staat is om hoogstens X transaksies in T sekondes te verwerk. Alle versoeke wat hierdie limiet oorskry, word weggegooi. Dit is redelik eenvoudig, maar dan kan jy vergeet van UX.

Beherende: die verbruiker moet 'n soort koppelvlak hê waardeur hy, afhangend van die vrag, die produsent se TPS kan beheer. Nie sleg nie, maar dit lê verpligtinge op die ontwikkelaars van die kliënt wat die las skep om hierdie koppelvlak te implementeer. Dit is vir ons onaanvaarbaar, aangesien blockchain in die toekoms geïntegreer sal word in 'n groot aantal reeds bestaande stelsels.

buffer: In plaas daarvan om die invoerdatastroom te probeer weerstaan, kan ons hierdie stroom buffer en dit teen die vereiste spoed verwerk. Dit is natuurlik die beste oplossing as ons 'n goeie gebruikerservaring wil bied. Ons het die buffer geïmplementeer deur 'n tou in RabbitMQ te gebruik.

Verspreide register vir wielestelle: 'n ervaring met Hyperledger Fabric

Twee nuwe aksies is by die skema gevoeg: (1) nadat 'n versoek aan die API aangekom het, word 'n boodskap met die parameters wat nodig is om 'n transaksie te bel in die tou geplaas, en die kliënt ontvang 'n boodskap dat die transaksie aanvaar is deur die stelsel, (2) die agterkant lees die data teen die spoed gespesifiseer in die opstelling vanaf tou; begin 'n transaksie en werk data in die statuswinkel op.
Nou kan jy die vormingstyd verhoog en die kapasiteit blokkeer soveel as wat jy wil, wat vertragings vir die gebruiker wegsteek.

Ander gereedskap

Niks is hier oor kettingkode gesê nie, want as 'n reël is daar niks om daarin te optimaliseer nie. Kettingkode moet so eenvoudig en veilig as moontlik wees - dit is al wat daarvan vereis word. Die raamwerk help ons om kettingkode eenvoudig en veilig te skryf CCKit van S7 Techlab en statiese ontleder herleef^CC.

Daarbenewens ontwikkel ons span 'n stel nutsprogramme om die werk met Fabric eenvoudig en aangenaam te maak: blokkettingverkenner, 'n nut vir outomatiese netwerkkonfigurasieveranderings (byvoeging/verwydering van organisasies, RAFT nodusse), nut vir herroeping van sertifikate en verwydering van identiteit. As jy wil bydra, is jy welkom.

Gevolgtrekking

Hierdie benadering laat jou toe om Hyperledger Fabric maklik te vervang met Quorum, ander private Ethereum-netwerke (PoA of selfs PoW), die werklike deurset aansienlik verminder, maar terselfdertyd normale UX handhaaf (beide vir gebruikers in die blaaier en vir geïntegreerde stelsels). Wanneer jy Stof met Ethereum in die skema vervang, hoef jy net die logika van die herprobeerdiens/versierder te verander van die verwerking van MVCC-konflikte na atoom-nonce-inkrement en herversending. Buffer en statusberging het dit moontlik gemaak om die reaksietyd van die blokvormingstyd te ontkoppel. Nou kan jy duisende bestellingsnodes byvoeg en nie bang wees dat blokke te dikwels gevorm word en die besteldiens laai nie.

Basies, dit is al wat ek wou deel. Ek sal bly wees as dit iemand help in hul werk.

Bron: will.com

Voeg 'n opmerking