Kerékpárok elosztott nyilvántartása: tapasztalat a Hyperledger szövettel

Helló, a DRD KP projekt csapatában dolgozom (elosztott adatnyilvántartás a kerékkészletek életciklusának figyelésére). Itt szeretném megosztani csapatunk tapasztalatait egy vállalati blokklánc fejlesztésével kapcsolatban ehhez a projekthez a technológiai korlátok mellett. A legtöbb esetben a Hyperledger Fabric-ről fogok beszélni, de az itt leírt megközelítés bármely engedélyezett blokkláncra extrapolálható. Kutatásunk végső célja, hogy olyan vállalati blokklánc-megoldásokat készítsünk, hogy a végtermék kellemes legyen a használata és karbantartása ne legyen túl nehéz.

Nem lesznek felfedezések, váratlan megoldások, és egyedi fejlesztésekről sem lesz itt szó (mert nekem nincs ilyenem). Csak szeretném megosztani szerény tapasztalataimat, megmutatni, hogy "lehetséges volt", és esetleg a megjegyzésekben olvasni valaki másnak a jó és nem túl jó döntések meghozatalában szerzett tapasztalatairól.

Probléma: a blokkláncok még nem méretezhetők

Manapság sok fejlesztő erőfeszítése arra irányul, hogy a blokklánc valóban kényelmes technológiává váljon, ne pedig egy gyönyörű csomagolásban ketyegő időzített bomba. Az állapotcsatornák, az optimista összesítés, a plazma és a szilánkolás mindennapossá válhatnak. Majd egyszer. Vagy talán a TON ismét hat hónappal elhalasztja az indulást, és a következő Plasma Group megszűnik. Hihetünk egy másik útitervben, és éjszaka ragyogó fehér papírokat olvashatunk, de itt és most tennünk kell valamit azzal, amink van. Csináld a szart.

A mostani projektben a csapatunkra háruló feladat általánosságban így néz ki: sok, több ezer főt elérő alany van, aki nem akar bizalmon alapuló kapcsolatokat építeni; olyan megoldást kell a DLT-re építeni, amely a közönséges PC-ken is működik speciális teljesítménykövetelmények nélkül, és nem rosszabb felhasználói élményt nyújt, mint bármely központi számviteli rendszer. A megoldás mögötti technológiának minimálisra kell csökkentenie a rosszindulatú adatmanipuláció lehetőségét – ezért van itt a blokklánc.

A whitepaperek és a média szlogenek azt ígérik, hogy a következő fejlesztés több millió tranzakciót tesz lehetővé másodpercenként. Mi ez valójában?

A Mainnet Ethereum jelenleg ~30 tps-en fut. Már csak emiatt is nehéz olyan blokkláncként felfogni, amely bármilyen módon is megfelel a vállalati igényeknek. Az engedélyezett megoldások közül ismertek a 2000 tps-t mutató benchmarkok (kvórum) vagy 3000 tps (Hyperledger szövet, valamivel kevesebb van a kiadványban, de ne feledje, hogy a benchmark a régi konszenzusos motoron történt). Volt kísérlet a Fabric radikális átdolgozására, amely nem a legrosszabb eredményt, 20000 tps-t adta, de ezek egyelőre csak akadémiai tanulmányok, amelyek stabil megvalósításukra várnak. Nem valószínű, hogy egy olyan vállalat, amely megengedheti magának, hogy fenntartson egy blokklánc-fejlesztői részleget, elviseli ezeket a mutatókat. De a probléma nem csak az átviteli sebességgel van, hanem a késleltetéssel is.

Késleltetés

A tranzakció kezdeményezésétől a rendszer általi végső jóváhagyásig eltelt késleltetés nemcsak az érvényesítési és rendelési szakaszon áthaladó üzenet sebességétől, hanem a blokkképzési paraméterektől is függ. Még ha a blokkláncunk lehetővé teszi is, hogy 1000000 10 488 tps-en commitáljuk, de egy XNUMX MB-os blokk kialakítása XNUMX percet vesz igénybe, könnyebb lesz a dolgunk?

Vessünk egy pillantást egy tranzakció életciklusára a Hyperledger Fabricban, hogy megértsük, mi igényel időt, és hogyan kapcsolódik a blokkképzési paraméterekhez.

Kerékpárok elosztott nyilvántartása: tapasztalat a Hyperledger szövettel
innen vették: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Az ügyfél létrehoz egy tranzakciót, elküldi a jóváhagyó partnereknek, ez utóbbiak szimulálják a tranzakciót (a lánckód által végrehajtott változtatásokat alkalmazzák az aktuális állapotra, de nem kötik le a főkönyvet) és megkapják az RWSet - kulcsneveket, verziókat, ill. a CouchDB gyűjteményéből vett értékek, (2) az endorserek visszaküldik az aláírt RWSet-et az ügyfélnek, (3) az ügyfél vagy ellenőrzi az összes szükséges társ (endorser) aláírását, majd elküldi a tranzakciót a megrendelő szolgáltatásnak. , vagy ellenőrzés nélkül elküldi (az ellenőrzés később is megtörténik), a megrendelő szolgáltatás blokkot képez, és (4) visszaküldi az összes társnak, nem csak az endorsernek; a társak ellenőrzik, hogy az olvasási halmazban lévő kulcsok verziói egyeznek-e az adatbázisban lévő verziókkal, az összes jóváhagyó aláírásával, és végül végrehajtják a blokkot.

De ez még nem minden. A „rendelő blokkot alkot” szavak mögött nem csak a tranzakciók sorrendje rejtőzik, hanem 3 egymást követő hálózati kérés is a vezetőtől a követőkhöz és vissza: a vezető üzenetet ad a naplóhoz, elküldi a követőknek, utóbbiak a naplójukat, visszaigazolást küld a sikeres replikációról a vezetőnek, a vezető véglegesíti az üzenetet, commit megerősítést küld a követőknek, a követők commit. Minél kisebb a blokk mérete és ideje, annál gyakrabban kell konszenzusra jutnia a megrendelőszolgálatnak. A Hyperledger Fabric két blokkképzési paraméterrel rendelkezik: BatchTimeout – blokkképzési idő és BatchSize – blokkméret (a tranzakciók száma és magának a blokknak a mérete bájtokban). Amint valamelyik paraméter eléri a határértéket, új blokk kerül kiadásra. Minél több megrendelő csomópont, ez annál tovább tart. Ezért növelnie kell a BatchTimeout és a BatchSize értéket. De mivel az RWSets verziószámú, minél nagyobbra tesszük a blokkot, annál nagyobb az MVCC ütközések valószínűsége. Ezenkívül a BatchTimeout növekedésével az UX katasztrofálisan leromlik. Számomra ésszerűnek és kézenfekvőnek tűnik a következő séma e problémák megoldására.

Hogyan kerüljük el a blokk véglegesítésének várakozását, és ne veszítsük el a tranzakció állapotát

Minél hosszabb a kialakítási idő és a blokkméret, annál nagyobb a blokklánc áteresztőképessége. Az egyik nem következik közvetlenül a másikból, de nem szabad elfelejteni, hogy a RAFT-ban a konszenzus kialakításához három hálózati kérés szükséges a vezetőtől a követőkig és vissza. Minél több rendelési csomópont, annál tovább tart. Minél kisebb a blokkképzés mérete és ideje, annál több ilyen kölcsönhatás. Hogyan lehet növelni a formázási időt és a blokk méretét anélkül, hogy a végfelhasználó számára növelné a rendszer válaszidejét?

Először is meg kell valahogy oldani a nagy blokkméret okozta MVCC konfliktusokat, amelyek különböző RWSeteket tartalmazhatnak ugyanazzal a verzióval. Nyilvánvaló, hogy a kliens oldalon (a blokklánc hálózattal kapcsolatban ez egy háttérprogram lehet, és komolyan is gondolom) MVCC konfliktuskezelő, amely lehet külön szolgáltatás vagy rendes dekorátor egy tranzakciót kezdeményező híváson keresztül újrapróbálkozási logikával.

Az újrapróbálkozás exponenciális stratégiával is megvalósítható, de ekkor a késleltetés is exponenciálisan csökken. Tehát vagy véletlenszerű újrapróbálkozást kell használni bizonyos kis határokon belül, vagy állandót. Figyelembe véve a lehetséges ütközéseket az első változatban.

A következő lépés az, hogy a kliens interakcióját a rendszerrel aszinkrontá tegyük, hogy ne várjon 15, 30 vagy 10000000 XNUMX XNUMX másodpercet, amit BatchTimeout-ként állítunk be. Ugyanakkor meg kell őrizni azt a képességet, hogy a tranzakció által kezdeményezett változások rögzítésre / ne kerüljenek rögzítésre a blokkláncban.
Egy adatbázis használható a tranzakciók állapotának tárolására. A legegyszerűbb lehetőség a CouchDB a könnyű kezelhetősége miatt: az adatbázis rendelkezik egy UI-val, egy REST API-val, és egyszerűen beállíthatja a replikációt és a felosztást. Csak létrehozhat egy különálló gyűjteményt ugyanabban a CouchDB-példányban, amelyet a Fabric a világállapotának tárolására használ. Az ilyen dokumentumokat tárolnunk kell.

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

Ezt a dokumentumot a rendszer beírja az adatbázisba, mielőtt a tranzakciót elküldi partnereknek, az entitásazonosítót visszaküldi a felhasználónak (ugyanazt az azonosítót használja kulcsként), ha ez egy létrehozási művelet, majd a Status, TxID és Error mezők frissítjük, amint releváns információk érkeznek a társaktól.

Kerékpárok elosztott nyilvántartása: tapasztalat a Hyperledger szövettel

Ebben a sémában a felhasználó nem várja meg, hogy a blokk végül kialakuljon, 10 másodpercig figyeli a forgó kereket a képernyőn, azonnali választ kap a rendszertől, és folytatja a munkát.

Azért választottuk a BoltDB-t a tranzakciók állapotainak tárolására, mert memóriát kell takarítanunk, és nem akarunk időt vesztegetni az önálló adatbázis-kiszolgálóval való hálózati interakcióra, különösen, ha ez az interakció egyszerű szöveges protokoll használatával történik. Egyébként, akár a CouchDB-t használod a fent leírt séma megvalósítására, akár csak a világállapot tárolására, mindenesetre érdemes optimalizálni az adatok CouchDB-ben való tárolását. Alapértelmezés szerint a CouchDB-ben a b-fa csomópontok mérete 1279 bájt, ami jóval kisebb, mint a lemezen lévő szektorméret, ami azt jelenti, hogy a fa olvasásához és újraegyensúlyozásához is több fizikai lemezelérésre lesz szükség. Az optimális méret megfelel a szabványnak Speciális formátum és 4 kilobájt. Az optimalizáláshoz be kell állítanunk a paramétert btree_chunk_size egyenlő: 4096 a CouchDB konfigurációs fájlban. A BoltDB esetében ilyen kézi beavatkozás nem szükséges.

Ellennyomás: puffer stratégia

De sok üzenet lehet. Többet, mint amennyit a rendszer elbír, megosztani az erőforrásokat a diagramon láthatóakon kívül még tucatnyi más szolgáltatással – és mindez még azokon a gépeken is hibátlanul működik, amelyeken az Intellij Idea futtatása rendkívül fárasztó lenne.

A kommunikáló rendszerek – a gyártó és a fogyasztó – eltérő áteresztőképességének problémáját különböző módon oldják meg. Lássuk, mit tehetünk.

Csepegés: azt állíthatjuk, hogy legfeljebb X tranzakciót tudunk feldolgozni T másodperc alatt. Minden, ezt a határt meghaladó kérést eldobunk. Elég egyszerű, de akkor elfelejtheted az UX-t.

Kontrolling: a fogyasztónak rendelkeznie kell valamilyen interfésszel, amelyen keresztül a terheléstől függően vezérelheti a termelő tps-it. Nem rossz, de kötelezettséget ró a load kliens fejlesztőire ennek a felületnek a megvalósítása. Számunkra ez elfogadhatatlan, mivel a blokkláncot a jövőben számos, régóta létező rendszerbe integrálják majd.

puffer: ahelyett, hogy megpróbálnánk ellenállni a bemeneti adatfolyamnak, pufferelhetjük ezt az adatfolyamot és feldolgozhatjuk a kívánt sebességgel. Nyilvánvalóan ez a legjobb megoldás, ha jó felhasználói élményt szeretnénk nyújtani. A puffert egy sor használatával implementáltuk a RabbitMQ-ban.

Kerékpárok elosztott nyilvántartása: tapasztalat a Hyperledger szövettel

Két új művelettel bővült a séma: (1) API kérés beérkezése után egy üzenet kerül sorba a tranzakció lehívásához szükséges paraméterekkel, és a kliens üzenetet kap arról, hogy a tranzakciót a rendszer elfogadta, ( 2) a háttérprogram a konfigurációban megadott sebességgel olvassa be az adatokat a sorból; tranzakciót kezdeményez és frissíti az adatokat az állapottárolóban.
Mostantól tetszőleges mértékben növelheti a felépítési időt és blokkolhatja a kapacitást, elrejtve a késéseket a felhasználó elől.

Egyéb eszközök

A lánckódról itt nem esett szó, mert általában nincs benne mit optimalizálni. A lánckódnak a lehető legegyszerűbbnek és biztonságosabbnak kell lennie – ez minden, ami szükséges tőle. A keretrendszer sokat segít a lánckód egyszerű és biztonságos megírásában. CSKit az S7 Techlabtól és a statikus analizátortól újraéleszteni^CC.

Ezenkívül csapatunk egy sor segédprogramot fejleszt ki, hogy a Fabric-cal való munkát egyszerűvé és élvezetessé tegye: blokklánc felfedező, segédprogram számára automatikus hálózati újrakonfigurálás (szervezetek hozzáadása/eltávolítása, RAFT csomópontok), segédprogram a számára tanúsítvány visszavonása és a személyazonosság eltávolítása. Ha szeretnél hozzájárulni, üdvözöljük.

Következtetés

Ez a megközelítés megkönnyíti a Hyperledger Fabric lecserélését Quorumra, más privát Ethereum hálózatokra (PoA vagy akár PoW), jelentősen csökkenti a valós átviteli sebességet, ugyanakkor fenntartja a normál felhasználói élményt (mind a böngészőben, mind az integrált rendszerek oldaláról). ). Amikor a Fabric-et Ethereummal cseréli le a sémában, csak az újrapróbálkozási szolgáltatás/dekorátor logikáját kell megváltoztatni az MVCC-konfliktusok kezeléséről atomi nonce-növekményre és újraküldésre. A pufferelés és az állapottárolás lehetővé tette a válaszidő és a blokkképzési idő leválasztását. Mostantól több ezer rendelési csomópontot adhat hozzá, és nem kell félnie attól, hogy túl gyakran képződnek blokkok, és betöltse a rendelési szolgáltatást.

Általában csak ennyit szerettem volna megosztani. Örülök, ha valakinek segít a munkájában.

Forrás: will.com

Hozzászólás