Distribuirani registar za kotače: Iskustvo s Hyperledger Fabricom

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

Neće biti otkrića, neočekivanih rješenja, niti će ovdje biti pokriveni nikakvi jedinstveni razvoji (jer ih nemam). Samo želim podijeliti svoje skromno iskustvo, pokazati da se "moglo" i možda u komentarima pročitati nečije iskustvo donošenja dobrih i loših odluka.

Problem: lanci blokova još nisu skalabilni

Danas su napori mnogih programera usmjereni na to da blockchain postane stvarno prikladna tehnologija, a ne tempirana bomba u lijepom omotu. Državni kanali, optimistično skupljanje, plazma i šarding mogu postati uobičajeni. Jednog dana. Ili će možda TON ponovno odgoditi lansiranje za šest mjeseci, a sljedeća Plasma grupa prestat će postojati. Možemo vjerovati u drugu mapu puta i noću čitati briljantne bijele knjige, ali ovdje i sada moramo učiniti nešto s onim što imamo. Obavi sranje.

Zadatak koji je dodijeljen našem timu u trenutnom projektu općenito izgleda ovako: postoji mnogo subjekata, kojih doseže nekoliko tisuća, koji ne žele graditi odnose na povjerenju; potrebno je na DLT-u izgraditi rješenje koje će raditi na običnim računalima bez posebnih zahtjeva za performansama i pružiti korisničko iskustvo ništa lošije od bilo kojeg centraliziranog računovodstvenog sustava. Tehnologija 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 milijune transakcija u sekundi. Što je zapravo?

Mainnet Ethereum trenutno radi pri ~30 tps. Već zbog toga teško ga je percipirati kao blockchain koji je na bilo koji način prikladan za potrebe poduzeća. Među dopuštenim rješenjima poznata su mjerila koja pokazuju 2000 tps (Kvorum) ili 3000 tps (Tkanina hiperledgera, ima nešto manje u publikaciji, ali imajte na umu da je benchmark proveden na starom consensus engineu). bio pokušaj radikalne prerade Fabrica, koji je dao ne baš najgore rezultate, 20000 tps, no zasad su to samo akademske studije koje čekaju svoju stabilnu implementaciju. Malo je vjerojatno da će se korporacija koja si može priuštiti održavanje odjela programera blockchaina pomiriti s takvim pokazateljima. Ali problem nije samo u propusnosti, tu je i latencija.

skrivenost

Kašnjenje od trenutka pokretanja transakcije do njenog konačnog odobrenja od strane sustava ne ovisi samo o brzini prolaska poruke kroz sve faze validacije i naručivanja, već io parametrima formiranja bloka. Čak i ako nam naš blockchain dopušta predaju pri 1000000 tps, ali je potrebno 10 minuta da se formira blok od 488 MB, hoće li nam biti lakše?

Pogledajmo pobliže životni ciklus transakcije u Hyperledger Fabricu kako bismo razumjeli za što je potrebno vrijeme i kako se to odnosi na parametre formiranja blokova.

Distribuirani registar za kotače: Iskustvo s Hyperledger Fabricom
preuzeto odavde: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Klijent formira transakciju, šalje je istovrsnim suradnicima, koji simuliraju transakciju (primjenjuju promjene koje je napravio lančani kod na trenutno stanje, ali ne obvezuju na glavnu knjigu) i primaju RWSet - imena ključeva, verzije i vrijednosti preuzete iz zbirke u CouchDB-u, ( 2) indosanti šalju potpisani RWSet natrag klijentu, (3) klijent ili provjerava potpise svih potrebnih peera (indosanti), a zatim šalje transakciju usluzi naručivanja , ili ga pošalje bez provjere (provjera će se ipak dogoditi kasnije), usluga naručitelja formira blok i ( 4) šalje natrag svim ravnopravnim korisnicima, a ne samo indosantima; ravnopravni korisnici provjeravaju odgovaraju li verzije ključeva u skupu za čitanje verzijama u bazi podataka, potpisima svih indosanta i na kraju predaju blok.

Ali to nije sve. Iza riječi "nalogodavac formira blok" krije se ne samo redoslijed transakcija, već i 3 uzastopna mrežna zahtjeva od voditelja do pratitelja i natrag: voditelj dodaje poruku u zapisnik, šalje pratiteljima, ovi dodaju u njihov dnevnik, pošalji potvrdu o uspješnoj replikaciji voditelju, voditelj predaje poruku, šalje potvrdu o predaji sljedbenicima, sljedbenici predaju. Što je manja veličina bloka i vrijeme, to će usluga naručitelja češće 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 dosegne ograničenje, izdaje se novi blok. Što je više čvorova naručitelja, to će dulje trajati. Stoga morate povećati BatchTimeout i BatchSize. Ali budući da su RWSetovi verzionirani, što veći blok napravimo, to je veća vjerojatnost MVCC sukoba. Osim toga, s povećanjem BatchTimeout-a, UX se katastrofalno pogoršava. Čini mi se razumnom i očitom sljedeća shema za rješavanje ovih problema.

Kako izbjeći čekanje na finalizaciju bloka i ne izgubiti status transakcije

Što je duže vrijeme formiranja i veličina bloka, veća je propusnost blockchaina. Jedno ne slijedi izravno iz drugoga, ali treba imati na umu da uspostavljanje konsenzusa u RAFT-u zahtijeva tri mrežna zahtjeva od voditelja do sljedbenika i natrag. Što je više čvorova reda, to će dulje 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 odgovora sustava za krajnjeg korisnika?

Prvo, trebate nekako riješiti MVCC sukobe uzrokovane velikom veličinom bloka, koji može uključivati ​​različite RWSetove s istom verzijom. Očito, na strani klijenta (u odnosu na blockchain mrežu, ovo bi mogao biti backend, i mislim to ozbiljno) MVCC rukovatelj sukobima, koji može biti zasebna usluga ili uobičajeni dekorater preko poziva koji pokreće transakciju s logikom ponovnog pokušaja.

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

Sljedeći korak je učiniti interakciju klijenta sa sustavom asinkronom 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 su promjene inicirane transakcijom zabilježene/ne zabilježene u blockchainu.
Baza podataka može se koristiti za pohranu statusa transakcija. Najlakša opcija je CouchDB zbog svoje jednostavne upotrebe: baza podataka ima korisničko sučelje iz kutije, REST API i možete jednostavno postaviti replikaciju i dijeljenje za nju. Možete jednostavno stvoriti zasebnu kolekciju u istoj CouchDB instanci koju Fabric koristi za pohranu svog svjetskog stanja. 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 ravnopravnim korisnicima, ID entiteta se vraća korisniku (isti ID se koristi kao ključ) ako je ovo operacija stvaranja, a zatim se polja Status, TxID i Greška ažurira kako se relevantne informacije primaju od kolega.

Distribuirani registar za kotače: Iskustvo s Hyperledger Fabricom

U ovoj shemi, korisnik ne čeka da se blok konačno formira, gledajući kotač koji se okreće na ekranu 10 sekundi, on dobiva trenutni odgovor od sustava i nastavlja s radom.

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

Povratni pritisak: strategija tampona

Ali poruka može biti puno. Više nego što sustav može podnijeti, dijeljenje resursa s desetak drugih usluga osim onih prikazanih na dijagramu - a sve bi to trebalo besprijekorno funkcionirati čak i na strojevima na kojima bi pokretanje Intellij Idea bilo iznimno zamorno.

Problem različite propusnosti komunikacijskih sustava, proizvođača i potrošača, rješava se na različite načine. Da vidimo što možemo učiniti.

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 tada možete zaboraviti na UX.

Kontroliranje: potrošač mora imati neko sučelje preko kojeg, ovisno o opterećenju, može kontrolirati tps proizvođača. Nije loše, ali nameće obvezu programerima klijenta za učitavanje da implementiraju ovo sučelje. Za nas je to neprihvatljivo, budući da će blockchain u budućnosti biti integriran u veliki broj dugo postojećih sustava.

poliranje: umjesto da se pokušavamo oduprijeti ulaznom toku podataka, možemo staviti u međuspremnik ovaj tok i obraditi ga potrebnom brzinom. Očito, ovo je najbolje rješenje ako želimo pružiti dobro korisničko iskustvo. Implementirali smo međuspremnik pomoću reda čekanja u RabbitMQ.

Distribuirani registar za kotače: Iskustvo s Hyperledger Fabricom

U shemu su dodane dvije nove radnje: (1) nakon što se primi API zahtjev, poruka se stavlja u red čekanja s parametrima potrebnim za pozivanje transakcije, a klijent prima poruku da je sustav prihvatio transakciju, ( 2) pozadina čita podatke brzinom navedenom u konfiguraciji iz reda čekanja; inicira transakciju i ažurira podatke u pohrani statusa.
Sada možete povećati vrijeme izrade 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 što 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 iz S7 Techlaba i statički analizator oživjeti^CC.

Osim toga, naš tim razvija skup uslužnih programa kako bi rad s Fabricom učinio jednostavnim i ugodnim: blockchain explorer, uslužni program za automatska rekonfiguracija mreže (dodaj/ukloni organizacije, RAFT čvorove), uslužni program za opoziv certifikata i uklanjanje identiteta. Ako želite doprinijeti, dobrodošli.

Zaključak

Ovaj pristup olakšava zamjenu Hyperledger Fabric s Quorumom, drugim privatnim Ethereum mrežama (PoA ili čak PoW), značajno smanjuje stvarnu propusnost, ali u isto vrijeme održava normalan UX (i za korisnike u pregledniku i sa strane integriranih sustava ). Prilikom zamjene Fabrica s Ethereumom u shemi, samo će se logika usluge ponovnog pokušaja/dekoratera morati promijeniti s rukovanja MVCC sukobima na atomski nonce inkrement i ponovno slanje. Spremanje u međuspremnik i pohranjivanje statusa omogućilo je odvajanje vremena odgovora od vremena formiranja bloka. Sada možete dodati tisuće čvorova naloga i ne bojati se da se blokovi formiraju prečesto i učitavaju uslugu naručivanja.

Općenito, ovo je sve što sam želio podijeliti. Bit će mi drago ako nekome pomogne u radu.

Izvor: www.habr.com

Dodajte komentar