Distributed Registry for Wheelsets: Iskustvo sa Hyperledger Fabric

Poštovani, radim u timu projekta DRD KP (distribuirani registar podataka za praćenje životnog ciklusa točkova). Ovdje bih želio podijeliti iskustvo našeg tima u razvoju poslovnog blockchaina za ovaj projekat pod ograničenjima tehnologije. Uglavnom ću govoriti o Hyperledger Fabric-u, ali pristup opisan ovdje može se ekstrapolirati na bilo koji odobreni blockchain. Krajnji cilj našeg istraživanja je pripremiti poslovna blockchain rješenja na takav način da je konačni proizvod ugodan za korištenje i da nije previše težak za održavanje.

Neće biti otkrića, neočekivanih rješenja, niti će ovdje biti pokriveni nikakvi jedinstveni razvoji (jer ih ja nemam). Želim samo podijeliti svoje skromno iskustvo, pokazati da je "bilo moguće" i, možda, u komentarima pročitati o nečijem iskustvu u donošenju dobrih i ne baš dobrih odluka.

Problem: blockchains još nisu skalabilni

Danas su napori mnogih programera usmjereni na to da blockchain bude zaista zgodna tehnologija, a ne tempirana bomba u prekrasnom omotu. Državni kanali, optimistični skup, plazma i dijeljenje mogu postati uobičajeni. Jednog dana. Ili će možda TON ponovo odgoditi lansiranje za šest mjeseci, a sljedeća Plasma grupa će prestati da postoji. Možemo vjerovati u još jedan putokaz i noću čitati briljantne bijele knjige, ali ovdje i sada moramo nešto učiniti s onim što imamo. Uradi sranje.

Zadatak koji je našem timu dodijeljen u trenutnom projektu generalno izgleda ovako: ima mnogo subjekata, do nekoliko hiljada, koji ne žele da grade odnose na povjerenju; potrebno je izgraditi na DLT-u rješenje koje će raditi na običnim računarima bez posebnih zahtjeva za performansama i pružati korisničko iskustvo ništa lošije od bilo kojeg centraliziranog računovodstvenog sistema. Tehnologija koja stoji iza rješenja trebala bi minimizirati mogućnost zlonamjerne manipulacije podacima – zbog čega je blockchain ovdje.

Slogani iz bijelih knjiga i medija obećavaju nam da će sljedeći razvoj omogućiti milione transakcija u sekundi. Šta je to zapravo?

Mainnet Ethereum trenutno radi na ~30 tps. Samo zbog toga, teško ga je percipirati kao blockchain koji je na bilo koji način pogodan za korporativne potrebe. Među dozvoljenim rješenjima poznata su mjerila koja pokazuju 2000 tps (kvorum) ili 3000 tps (Hyperledger Fabric, ima nešto manje u publikaciji, ali imajte na umu da je benchmark proveden na starom konsenzus motoru). Bio pokušaj radikalne prerade Fabric, koji je dao ne najgore rezultate, 20000 tps, ali za sada su to samo akademske studije koje čekaju svoju stabilnu implementaciju. Malo je vjerovatno da će se korporacija koja može priuštiti održavanje odjela blockchain programera podnijeti takve pokazatelje. Ali problem nije samo u propusnosti, postoji i kašnjenje.

latentnost

Kašnjenje od trenutka kada je transakcija pokrenuta do njenog konačnog odobrenja od strane sistema zavisi ne samo od brzine prolaska poruke kroz sve faze validacije i naručivanja, već i od parametara formiranja bloka. Čak i ako nam naš blockchain dopušta da izvršimo 1000000 tps, ali je potrebno 10 minuta da formiramo blok od 488 MB, hoće li nam biti lakše?

Pogledajmo bliže životni ciklus transakcije u Hyperledger Fabric-u da bismo razumjeli za šta je potrebno vrijeme i kako se to odnosi na parametre formiranja bloka.

Distributed Registry for Wheelsets: Iskustvo sa Hyperledger Fabric
preuzeto odavde: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Klijent formira transakciju, šalje je vršnjacima koji podržavaju, oni simuliraju transakciju (primjenjuju promjene koje je izvršio lančani kod na trenutno stanje, ali se ne obavezuju na knjigu) i primaju RWSet - nazive ključeva, verzije i vrijednosti preuzete iz kolekcije u CouchDB-u, (2) indosanti šalju potpisani RWSet nazad klijentu, (3) klijent ili provjerava potpise svih potrebnih peer-a (indosatora), a zatim šalje transakciju servisu naručivanja , ili ga šalje bez verifikacije (provera će se ipak obaviti kasnije), usluga naručivanja formira blok i ( 4) šalje nazad svim kolegama, a ne samo indosantima; vršnjaci provjeravaju da li se verzije ključeva u skupu za čitanje podudaraju s verzijama u bazi podataka, potpisima svih indosora i konačno urezuju blok.

Ali to nije sve. Iza reči „naručilac formira blok“ krije se ne samo redosled transakcija, već i 3 uzastopna mrežna zahteva od lidera do pratilaca i nazad: lider dodaje poruku u dnevnik, šalje sledbenicima, a ovi dodaju u njihov dnevnik, pošalji potvrdu o uspješnoj replikaciji lideru, vođa urezuje poruku, šalje potvrdu urezivanja sljedbenicima, sljedbenici se urezuju. Što je manja veličina bloka i vrijeme, to će češće servis za naručivanje morati uspostaviti konsenzus. Hyperledger Fabric ima dva parametra formiranja bloka: BatchTimeout - vrijeme formiranja bloka i BatchSize - veličina bloka (broj transakcija i veličina samog bloka u bajtovima). Čim jedan od parametara dostigne granicu, izdaje se novi blok. Što je više čvorova naručioca, to će duže trajati. Stoga morate povećati vrijeme batchtimeouta i batchSize. Ali pošto su RWSetovi verzionisani, što veći blok napravimo, veća je verovatnoća MVCC konflikta. Osim toga, s povećanjem BatchTimeout-a, UX se katastrofalno degradira. Čini mi se razumnom i očiglednom sljedeća shema za rješavanje ovih problema.

Kako izbjeći čekanje finalizacije bloka i ne izgubiti trag o statusu transakcije

Što je duže vrijeme formiranja i veličina bloka, to je veća propusnost blockchaina. Jedno ne proizilazi direktno iz drugog, ali treba imati na umu da su za uspostavljanje konsenzusa u RAFT-u potrebna tri mrežna zahtjeva od lidera do sljedbenika i nazad. Što je više čvorova narudžbe, to će duže trajati. Što je manja veličina i vrijeme formiranja bloka, to je više takvih interakcija. Kako povećati vrijeme formiranja i veličinu bloka bez povećanja vremena odziva sistema za krajnjeg korisnika?

Prvo, morate nekako riješiti MVCC konflikte uzrokovane velikom veličinom bloka, koja može uključivati ​​različite RWSetove s istom verzijom. Očigledno, na strani klijenta (u odnosu na blockchain mrežu, ovo može biti backend, i mislim to) MVCC obrađivač konflikta, koji može biti ili zasebna usluga ili običan dekorator preko poziva koji pokreće transakciju s logikom ponovnog pokušaja.

Ponovni pokušaj se može implementirati sa eksponencijalnom strategijom, ali će se tada i latencija eksponencijalno degradirati. Dakle, trebali biste koristiti ili nasumični ponovni pokušaj unutar određenih malih ograničenja, ili konstantan. S obzirom na moguće sudare u prvoj varijanti.

Sljedeći korak je da interakciju klijenta sa sistemom učinimo asinhronom tako da ne čeka 15, 30 ili 10000000 sekundi, što ćemo postaviti kao BatchTimeout. Ali u isto vrijeme, potrebno je zadržati mogućnost da se osigura da se promjene inicirane transakcijom bilježe/ne bilježe u blockchain-u.
Baza podataka se može koristiti za pohranjivanje statusa transakcija. Najlakša opcija je CouchDB zbog svoje lakoće upotrebe: baza podataka ima korisnički interfejs iz kutije, REST API i lako možete podesiti replikaciju i dijeljenje za nju. Možete jednostavno kreirati zasebnu kolekciju u istoj CouchDB instanci koju Fabric koristi za pohranjivanje svog stanja svijeta. Moramo pohraniti dokumente ove vrste.

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

Ovaj dokument se upisuje u bazu podataka prije nego što se transakcija pošalje kolegama, ID entiteta se vraća korisniku (isti ID se koristi kao ključ) ako je ovo operacija kreiranja, a zatim se polja Status, TxID i Error ažuriraju kako relevantne informacije budu primljene od kolega.

Distributed Registry for Wheelsets: Iskustvo sa Hyperledger Fabric

U ovoj shemi korisnik ne čeka da se blok konačno formira, gledajući točak koji se vrti na ekranu 10 sekundi, on dobija trenutni odgovor od sistema i nastavlja s radom.

Odabrali smo BoltDB za pohranjivanje statusa transakcija jer moramo uštedjeti memoriju i ne želimo gubiti vrijeme na mrežnu interakciju sa samostalnim serverom baze podataka, posebno kada se ova interakcija odvija korištenjem protokola običnog teksta. Usput, bilo da koristite CouchDB za implementaciju gore opisane šeme ili samo za pohranu stanja svijeta, u svakom slučaju, ima smisla optimizirati način na koji se podaci pohranjuju u CouchDB. Podrazumevano, u CouchDB-u, veličina čvorova b-stabla je 1279 bajtova, što je mnogo manje od veličine sektora na disku, što znači da će i čitanje i ponovno balansiranje stabla zahtijevati više pristupa fizičkom disku. Optimalna veličina zadovoljava standard Napredni format i iznosi 4 kilobajta. Za optimizaciju, moramo postaviti parametar btree_chunk_size jednaka 4096 u CouchDB konfiguracijskoj datoteci. Za BoltDB takva ručna intervencija nije potrebno.

Protupritisak: strategija tampon

Ali može biti puno poruka. Više nego što sistem može da podnese, deljenje resursa sa desetak drugih servisa osim onih prikazanih na dijagramu - i sve ovo bi trebalo da funkcioniše besprekorno čak i na mašinama na kojima bi pokretanje Intellij Idea bilo izuzetno zamorno.

Problem različite propusnosti komunikacionih sistema, proizvođača i potrošača, rešava se na različite načine. Hajde da vidimo šta možemo da uradimo.

Ispuštanje: možemo tvrditi da možemo obraditi najviše X transakcija u T sekundi. Svi zahtjevi koji prelaze ovo ograničenje se odbacuju. Prilično je jednostavno, ali onda možete zaboraviti na UX.

kontrolni: potrošač mora imati neki interfejs preko kojeg, ovisno o opterećenju, može kontrolirati TPS proizvođača. Nije loše, ali nameće obavezu programerima klijenta za učitavanje da implementiraju ovaj interfejs. Za nas je to neprihvatljivo, jer će blockchain u budućnosti biti integrisan u veliki broj već dugo postojećih sistema.

Međuspremnik: umjesto da pokušavamo da se odupremo ulaznom toku podataka, možemo taj tok baferovati i obraditi ga potrebnom brzinom. Očigledno, ovo je najbolje rješenje ako želimo pružiti dobro korisničko iskustvo. Bafer smo implementirali koristeći red u RabbitMQ-u.

Distributed Registry for Wheelsets: Iskustvo sa Hyperledger Fabric

U šemu su dodane dvije nove akcije: (1) nakon što je primljen API zahtjev, poruka se stavlja u red čekanja s parametrima potrebnim za pozivanje transakcije, a klijent prima poruku da je transakcija prihvaćena od strane sistema, ( 2) backend čita podatke brzinom navedenom u konfiguraciji iz reda; inicira transakciju i ažurira podatke u spremištu statusa.
Sada možete povećati vrijeme izgradnje i blokirati kapacitet koliko god želite, skrivajući kašnjenja od korisnika.

Ostali alati

Ovdje ništa nije rečeno o lančanom kodu, jer se u njemu obično nema šta optimizirati. Lančani kod bi trebao biti što jednostavniji i sigurniji - to je sve što se od njega traži. Framework nam puno pomaže da jednostavno i sigurno napišemo lančani kod. CSKit od S7 Techlab i statičkog analizatora oživi^CC.

Osim toga, naš tim razvija skup uslužnih programa kako bi rad s Fabric-om učinio jednostavnim i ugodnijim: blockchain explorer, uslužni program za automatska rekonfiguracija mreže (dodavanje/uklanjanje organizacija, RAFT čvorova), uslužni program za opoziv certifikata i uklanjanje identiteta. Ako želite da doprinesete, dobrodošli.

zaključak

Ovaj pristup olakšava zamjenu Hyperledger Fabric-a s Quorumom, drugim privatnim Ethereum mrežama (PoA ili čak PoW), značajno smanjuje stvarnu propusnost, ali istovremeno održava normalan UX (kako za korisnike u pretraživaču tako i sa strane integriranih sistema ). Prilikom zamjene Fabric-a sa Ethereum-om u shemi, samo će logika servisa/dekoratora ponovnog pokušaja biti promijenjena iz rukovanja MVCC sukobima na atomsko povećanje nonce i ponovno slanje. Baferovanje i skladištenje statusa omogućili su da se vreme odgovora odvoji od vremena formiranja bloka. Sada možete dodati hiljade čvorova narudžbi i ne plašiti se da se blokovi formiraju prečesto i učitavaju uslugu naručivanja.

Generalno, ovo je sve što sam želeo da podelim. Biće mi drago ako nekome pomogne u radu.

izvor: www.habr.com

Dodajte komentar