Distribuovaný registr pro dvojkolí: Zkušenost s Hyperledger Fabric

Dobrý den, pracuji v týmu projektu DRD KP (distribuovaný datový registr pro sledování životního cyklu dvojkolí). Zde se chci podělit o zkušenosti našeho týmu s vývojem podnikového blockchainu pro tento projekt v rámci technologických omezení. Většinou budu mluvit o Hyperledger Fabric, ale zde popsaný přístup lze extrapolovat na jakýkoli povolený blockchain. Konečným cílem našeho výzkumu je připravit podniková blockchainová řešení tak, aby byl výsledný produkt příjemný na používání a nebyl příliš náročný na údržbu.

Nebudou zde žádné objevy, neočekávaná řešení a nebudou zde zdůrazňovány žádné jedinečné události (protože žádné nemám). Chci se jen podělit o svou skromnou zkušenost, ukázat, že „bylo to možné“ a možná si v komentářích přečíst o zkušenostech jiných lidí s dobrými a ne tak dobrými rozhodnutími.

Problém: Blockchainy se zatím neškálují

Dnes je úsilí mnoha vývojářů zaměřeno na to, aby se blockchain stal skutečně pohodlnou technologií a ne časovanou bombou v krásném obalu. Státní kanály, optimistický rollup, plazma a sharding se pravděpodobně stanou samozřejmostí. Někdy. Nebo možná TON znovu odloží spuštění o šest měsíců a další Plasma Group přestane existovat. Můžeme věřit dalšímu plánu a v noci číst brilantní bílé knihy, ale tady a teď musíme něco udělat s tím, co máme. Udělej to.

Úkol stanovený pro náš tým v aktuálním projektu vypadá obecně takto: existuje mnoho subjektů, dosahující několika tisíc, kteří nechtějí budovat vztahy na důvěře; Na DLT je nutné postavit řešení, které bude fungovat na běžných počítačích bez zvláštních požadavků na výkon a poskytne uživatelskou zkušenost o nic horší než jakékoli centralizované účetní systémy. Technologie za řešením musí minimalizovat možnost zlomyslné manipulace s daty – proto je tu blockchain.

Slogany z whitepapers a médií nám slibují, že další vývoj nám umožní provádět miliony transakcí za sekundu. co to vlastně je?

Mainnet Ethereum aktuálně běží na ~30 tps. Už jen kvůli tomu je obtížné jej vnímat jako blockchain jakýmkoli způsobem vhodný pro firemní potřeby. Mezi povolená řešení jsou benchmarky ukazující 2000 tps (Kvorum) nebo 3000 tps (Hyperledger Fabric, je v publikaci o něco méně, ale je třeba vzít v úvahu, že benchmark byl proveden na starém konsensuálním enginu). Byl pokus o radikální zpracování Fabric, který dal ne nejhorší výsledky, 20000 XNUMX tps, ale zatím se jedná pouze o akademický výzkum, který čeká na stabilní implementaci. Je nepravděpodobné, že korporace, která si může dovolit udržovat oddělení vývojářů blockchainu, se s takovými ukazateli smíří. Problémem ale není jen propustnost, ale také latence.

Latence

Prodleva od okamžiku zahájení transakce do jejího konečného schválení systémem závisí nejen na rychlosti, jakou zpráva projde všemi fázemi validace a objednávání, ale také na parametrech tvorby bloku. I když nám náš blockchain umožňuje provádět zavázání rychlostí 1000000 10 488 tps, ale vygenerování bloku o velikosti XNUMX MB vyžaduje XNUMX minut, bude to pro nás jednodušší?

Podívejme se blíže na životní cyklus transakcí v Hyperledger Fabric, abychom pochopili, kde se tráví čas a jak to souvisí s parametry generování bloků.

Distribuovaný registr pro dvojkolí: Zkušenost s Hyperledger Fabric
převzato odtud: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Klient vytvoří transakci, odešle ji schvalujícím partnerům, tito simulují transakci (aplikují změny provedené řetězovým kódem na aktuální stav, ale nepotvrdí se v účetní knize) a obdrží RWSet - názvy klíčů, verze a hodnoty ​​převzato z kolekce v CouchDB, (2) indosanti zašlou klientovi zpět podepsanou sadu RWSet, (3) klient buď zkontroluje přítomnost podpisů všech potřebných peerů (endorserů), a poté odešle transakci objednávkové službě , nebo jej odešle bez ověření (kontrola stejně proběhne později), objednávková služba vytvoří blok a ( 4) odešle zpět všem peerům, nejen indosantům; kolegové zkontrolují, zda se verze klíčů v sadě pro čtení shodují s verzemi v databázi, že všichni schvalující mají podpisy, a nakonec blok potvrdí.

Ale to není vše. Slova „objednatel tvoří blok“ skrývají nejen řazení transakcí, ale také 3 po sobě jdoucí síťové požadavky od vedoucího k následovníkům a zpět: vedoucí přidá zprávu do logu, odešle ji sledujícím, ti ji přidá do jejich logu, odešle potvrzení o úspěšné replikaci vedoucímu, vedoucí potvrdí zprávu , odešle potvrzení potvrzení následovníkům, následovníci commit. Čím menší je velikost a doba vytvoření bloku, tím častěji bude muset objednávková služba dosáhnout konsensu. Hyperledger Fabric má dva parametry pro tvorbu bloku: BatchTimeout - čas vytvoření bloku a BatchSize - velikost bloku (počet transakcí a velikost samotného bloku v bajtech). Jakmile jeden z parametrů dosáhne limitu, uvolní se nový blok. Čím více uzlů objednávky, tím déle to bude trvat. Proto je třeba zvýšit BatchTimeout a BatchSize. Ale protože RWSets jsou verzované, čím větší blok vytvoříme, tím vyšší je pravděpodobnost konfliktů MVCC. Navíc, jak se BatchTimeout zvyšuje, UX katastrofálně degraduje. Následující schéma řešení těchto problémů se mi zdá rozumné a zřejmé.

Jak se vyhnout čekání na finalizaci bloku a neztratit možnost sledovat stav transakce

Čím delší je doba vytvoření a velikost bloku, tím vyšší je propustnost blockchainu. Jedno z druhého přímo nevyplývá, ale je třeba mít na paměti, že nastolení konsenzu v RAFT vyžaduje tři síťové požadavky od vůdce k následovníkům a zpět. Čím více uzlů objednávky, tím déle to bude trvat. Čím menší je velikost a doba vzniku bloku, tím více takových interakcí je. Jak zvýšit dobu generování a velikost bloku bez zvýšení doby odezvy systému pro koncového uživatele?

Nejprve musíme nějak vyřešit konflikty MVCC způsobené velkou velikostí bloku, který může zahrnovat různé sady RWS se stejnou verzí. Je zřejmé, že na straně klienta (ve vztahu k blockchainové síti by to mohl být backend, a to myslím vážně) potřebujete Ovladač konfliktů MVCC, což může být buď samostatná služba, nebo běžný dekorátor nad voláním, které iniciuje transakci s logikou opakování.

Opakovaný pokus lze implementovat pomocí exponenciální strategie, ale pak se latence sníží stejně exponenciálně. Měli byste tedy použít buď náhodné opakování v určitých malých mezích, nebo konstantní. S ohledem na možné kolize v první možnosti.

Dalším krokem je, aby byla interakce klienta se systémem asynchronní, aby nečekal 15, 30 nebo 10000000 sekund, které nastavíme jako BatchTimeout. Ale zároveň je nutné zachovat možnost ověřit, že změny iniciované transakcí jsou/nejsou zaznamenány v blockchainu.
K uložení stavu transakce lze použít databázi. Nejjednodušší možností je CouchDB kvůli snadnému použití: databáze má uživatelské rozhraní z krabice, REST API a můžete pro ni snadno nastavit replikaci a sharding. Můžete jednoduše vytvořit samostatnou kolekci ve stejné instanci CouchDB, která používá Fabric k uložení svého světového stavu. Tyto typy dokumentů musíme uchovávat.

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

Tento dokument je zapsán do databáze před odesláním transakce k peerům, ID entity je vráceno uživateli (stejné ID je použito jako klíč), pokud se jedná o operaci vytvoření, a poté jsou pole Status, TxID a Error aktualizovány, jak jsou relevantní informace obdrženy od kolegů.

Distribuovaný registr pro dvojkolí: Zkušenost s Hyperledger Fabric

V tomto schématu uživatel nečeká na definitivní vytvoření bloku, sleduje točící se kolo na obrazovce po dobu 10 sekund, obdrží okamžitou odpověď od systému a pokračuje v práci.

Pro ukládání stavů transakcí jsme zvolili BoltDB, protože potřebujeme šetřit paměť a nechceme ztrácet čas síťovou interakcí se samostatným databázovým serverem, zvláště když k této interakci dochází pomocí protokolu prostého textu. Mimochodem, ať už používáte CouchDB k implementaci výše popsaného schématu nebo jednoduše k ukládání světového stavu, v každém případě má smysl optimalizovat způsob ukládání dat v CouchDB. Ve výchozím nastavení je v CouchDB velikost uzlů b-stromu 1279 bajtů, což je mnohem méně než velikost sektoru na disku, což znamená, že jak čtení, tak vyvažování stromu bude vyžadovat větší fyzický přístup k disku. Optimální velikost odpovídá standardu Pokročilý formát a má 4 kilobajty. Pro optimalizaci musíme nastavit parametr btree_chunk_size se rovná 4096 v konfiguračním souboru CouchDB. U BoltDB takový ruční zásah není nutné.

Protitlak: vyrovnávací strategie

Ale zpráv může být hodně. Více, než systém zvládne, sdílení zdrojů s tuctem dalších služeb kromě těch, které jsou znázorněny na diagramu – a to vše by mělo bezchybně fungovat i na počítačích, na kterých by spouštění Intellij Idea bylo extrémně únavné.

Problém rozdílné kapacity komunikujících systémů, výrobce a spotřebitele, je řešen různými způsoby. Podívejme se, co bychom mohli udělat.

Shazování: Můžeme tvrdit, že jsme schopni zpracovat maximálně X transakcí za T sekund. Všechny požadavky překračující tento limit jsou zahozeny. To je docela jednoduché, ale pak můžete zapomenout na UX.

Ovládání: spotřebitel musí mít nějaké rozhraní, přes které může v závislosti na zatížení ovládat TPS výrobce. Není to špatné, ale ukládá to vývojářům klienta, který vytváří zátěž, povinnost implementovat toto rozhraní. To je pro nás nepřijatelné, protože blockchain bude v budoucnu integrován do velkého množství již existujících systémů.

buffering: Místo toho, abychom se snažili bránit vstupnímu datovému toku, můžeme tento tok vyrovnávací paměti a zpracovávat ho požadovanou rychlostí. Je zřejmé, že toto je nejlepší řešení, pokud chceme poskytnout dobrou uživatelskou zkušenost. Vyrovnávací paměť jsme implementovali pomocí fronty v RabbitMQ.

Distribuovaný registr pro dvojkolí: Zkušenost s Hyperledger Fabric

Do schématu byly přidány dvě nové akce: (1) po příchodu požadavku na API je do fronty umístěna zpráva s parametry nezbytnými pro vyvolání transakce a klient obdrží zprávu, že transakce byla přijata systém, (2) backend čte data z fronty rychlostí zadanou v konfiguraci; zahájí transakci a aktualizuje data ve stavovém úložišti.
Nyní můžete zvýšit dobu vytváření a blokovat kapacitu, jak chcete, a skrýt zpoždění před uživatelem.

Jiné nástroje

O řetězovém kódu zde nebylo nic řečeno, protože v něm zpravidla není co optimalizovat. Řetězový kód by měl být co nejjednodušší a bezpečný – to je vše, co se od něj vyžaduje. Framework nám pomáhá psát řetězový kód jednoduše a bezpečně CCKit od S7 Techlab a statický analyzátor oživit^CC.

Náš tým navíc vyvíjí sadu utilit, aby byla práce s Fabric jednoduchá a zábavná: blockchain průzkumník, nástroj pro automatické změny konfigurace sítě (přidávání/odebírání organizací, uzlů RAFT), nástroj pro zneplatnění certifikátů a odebrání identity. Pokud chcete přispět, jste vítáni.

Závěr

Tento přístup umožňuje snadno nahradit Hyperledger Fabric za Quorum, jiné privátní sítě Ethereum (PoA nebo i PoW), výrazně snížit skutečnou propustnost, ale zároveň zachovat normální UX (jak pro uživatele v prohlížeči, tak pro integrované systémy). Když ve schématu nahradíte Fabric Ethereem, budete muset změnit pouze logiku služby/dekorátoru opakování ze zpracování konfliktů MVCC na atomický přírůstek nonce a opětovné odeslání. Ukládání do vyrovnávací paměti a stavové ukládání umožnilo oddělit dobu odezvy od doby vytvoření bloku. Nyní můžete přidávat tisíce objednávkových uzlů a nebát se, že se bloky tvoří příliš často a načítat objednávkovou službu.

V podstatě to je vše, co jsem chtěl sdílet. Budu rád, když to někomu pomůže v jeho práci.

Zdroj: www.habr.com

Přidat komentář