Een veelgestelde vraag van niet-technische experts over elke gedistribueerd systeem is āHoeveel TPS heeft uw blockchain?ā. Echter, het getal dat als antwoord wordt gegeven, heeft meestal weinig te maken met wat de vraagsteller daadwerkelijk wil weten. In werkelijkheid wilde hij vragen āpast uw blockchain bij mijn zakelijke vereisten?ā, en deze vereisten zijn geen enkel getal, maar een veelheid aan voorwaarden ā zowel de fouttolerantie van het netwerk als de vereisten voor finaliteit, de grootte, het karakter van transacties en vele andere parameters. Dus het antwoord op de vraag āhoeveel TPSā zal zeker niet eenvoudig zijn en bijna nooit compleet. Een gedistribueerd systeem met tientallen en honderden knooppunten die vrij complexe berekeningen uitvoeren, kan zich in een enorm aantal verschillende toestanden bevinden, die verband houden met de staat van het netwerk, de inhoud van de blockchain, technische storingen, economische problemen, aanvallen op het netwerk en vele andere redenen. De fasen waarin prestatieproblemen kunnen optreden, verschillen van traditionele services, en de server van een blockchain-netwerk is een netwerkservice die de functionaliteit van een database, webserver en torrentclient combineert, wat het uiterst complex maakt qua belastingprofiel op alle subsysteem: CPU, geheugen, netwerk, opslag.
Het is zo dat gedecentraliseerde netwerken en blockchains vrij specifieke en ongebruikelijke software zijn voor ontwikkelaars van gecentraliseerde software. Daarom wil ik belangrijke aspecten van de prestaties en veerkracht van gedecentraliseerde netwerken belichten, benaderingen voor hun meting en het vinden van bottlenecks. We zullen verschillende prestatieproblemen onderzoeken die de snelheid van de service-aanbieding aan blockchain-gebruikers beperken en de kenmerken opmerken die typisch zijn voor dit soort software.
Fasen van de service-aanvraag door een blockchain-klant
Om eerlijk te kunnen spreken over de kwaliteit van een enigszins complexe service, moeten niet alleen de gemiddelde waarden, maar ook de maximale/minimale waarden, mediaan en percentielen in overweging worden genomen. Theoretisch gezien kan men 1000 tps noemen in een blockchain, maar als 900 transacties met hoge snelheid worden uitgevoerd, terwijl 100 'vastlopen' gedurende enkele seconden, dan is de gemiddelde tijd die over alle transacties wordt verzameld geen eerlijke maatstaf voor de klant die zijn transactie niet binnen enkele seconden kon voltooien. Tijdelijke 'gaten', veroorzaakt door gemiste consensusrondes of netwerk splitsingen, kunnen de service aanzienlijk verslechteren, die op teststations een uitstekende performance toonde.
Om dergelijke knelpunten te identificeren, is het essentieel om goed te begrijpen op welke momenten de echte blockchain problemen kan ondervinden bij het bedienen van gebruikers. Laten we de cyclus van levering en verwerking van transacties beschrijven, evenals het verkrijgen van een nieuwe status van de blockchain, waaruit de klant kan opmaken dat zijn transactie is verwerkt en geregistreerd.
- de transactie wordt gevormd op de klantzijde
- de transactie wordt ondertekend op de klantzijde
- de klant kiest een van de nodes en verzendt zijn transactie naar die node
- de klant meldt zich aan voor updates van de state database van de node, in afwachting van de resultaten van de uitvoering van zijn transactie
- de node verspreidt de transactie via het p2p-netwerk
- meerdere of ƩƩn BP (block producer) verwerkt de verzamelde transacties en werkt de state database bij
- BP vormt een nieuwe blok door het vereiste aantal transacties te verwerken
- BP verspreidt de nieuwe blok via het p2p-netwerk
- de nieuwe blok wordt afgeleverd aan de node waar de klant toegang toe heeft
- de node werkt de state database bij
- de node ziet de update die betrekking heeft op de klant en stuurt hem een melding over de transactie
Laten we deze stappen nu gedetailleerd bekijken en de potentiĆ«le prestatieproblemen op elk van deze stappen beschrijven. In tegenstelling tot gecentraliseerde systemen, zullen we ook de uitvoering van code aan de netwerk clients bekijken. Bij het meten van de tps wordt de verwerkingstijd van transacties vaak verzameld van nodes in plaats van van de client ā dit is niet helemaal eerlijk. Voor de client is het niet relevant hoe snel de node zijn transactie heeft verwerkt; het belangrijkste voor hem is het moment waarop betrouwbare informatie over deze transactie, die in de blockchain is opgenomen, beschikbaar voor hem wordt. Deze metriek is in feite de transactie-uitvoeringstijd. Dit betekent dat verschillende clients, zelfs wanneer ze dezelfde transactie verzenden, totaal verschillende tijden kunnen ontvangen, afhankelijk van het kanaal, de belasting en de nabijheid van de node, enzovoort. Daarom is het absoluut noodzakelijk om deze tijd op de clients te meten, omdat precies deze parameter moet worden geoptimaliseerd.
Voorbereiding van de transactie aan de kant van de client
Laten we beginnen met de eerste twee punten: de transactie wordt gevormd en ondertekend door de client. Het klinkt misschien vreemd, maar dit kan ook een bottleneck zijn voor de prestaties van de blockchain vanuit het perspectief van de client. Dit is ongebruikelijk voor gecentraliseerde diensten, waar alle berekeningen en dataverwerkingen door hen worden uitgevoerd, en de client gewoon een korte aanvraag voorbereidt die een grote hoeveelheid data of berekeningen kan opvragen, en het resultaat ontvangt. In blockchain-systemen wordt de clientcode steeds krachtiger, terwijl de blockchain-kern steeds lichter wordt, en omvangrijke rekentaken worden doorgaans aan de client software gegeven. In blockchains zijn er clients die vrij lang ƩƩn transactie kunnen voorbereiden (ik heb het over verschillende merkle bewijsstukjes, beknopte bewijsstukken, threshold handtekeningen en andere complexe bewerkingen aan de kant van de client). Een goed voorbeeld van lichte on-chain verificatie en zware voorbereiding van een transactie aan de client is het bewijs van lidmaatschap van een lijst op basis van een Merkle-boom. .
Vergeet ook niet dat de clientcode niet alleen transacties naar de blockchain verzendt, maar eerst de status van de blockchain opvraagt ā en deze activiteit kan invloed hebben op de belasting van het netwerk en de blockchain-nodes. Dus, bij het uitvoeren van metingen, is het verstandig om het gedrag van de clientcode zo volledig mogelijk te emuleren. Zelfs als er in uw blockchain alleen maar gewone lichte clients zijn die een standaard digitale handtekening zetten op een eenvoudige transactie voor het overdragen van een bepaald asset, neemt het aantal massa-berekeningen aan de clientzijde elk jaar toe, worden de crypto-algoritmen sterker, en deze verwerkingscomponent kan in de toekomst een significante bottleneck worden. Wees daarom voorzichtig en mis de situatie niet waarin voor een transactie die 3,5 seconden duurt, 2,5 seconden gaat naar de voorbereiding en ondertekening van de transactie, en 1,0 seconde naar het verzenden naar het netwerk en het wachten op een antwoord. Om de risico's van deze bottleneck te beoordelen, is het belangrijk om metrics van clientmachines te verzamelen, en niet alleen van de blockchain-nodes.
Transactie verzenden en de status ervan volgen
De volgende stap is het verzenden van de transactie naar de gekozen blockchain-node en het ontvangen van de status van opname in de pool van transacties. Deze stap lijkt op een reguliere database-aanroep, de node moet de transactie in de pool opnemen en beginnen met het verspreiden van informatie erover via het p2p-netwerk. De benadering voor het beoordelen van de prestaties hier is vergelijkbaar met die van traditionele microservices Web API's, waarbij de transacties in blockchains actief kunnen worden bijgewerkt en hun status kunnen wijzigen. In feite kan de informatie over een transactie in sommige blockchains meerdere keren worden bijgewerkt, bijvoorbeeld bij overschakelingen tussen forks van de keten of wanneer BP aangeven voornemen om de transactie in een blok op te nemen. Beperkingen op de grootte van deze pool en het aantal transacties daarin kunnen invloed hebben op de prestaties van de blockchain. Als de transactiepool vol is tot de maximaal mogelijke grootte, of niet in het RAM past ā kan de netwerksnelheid aanzienlijk dalen. Blockchains hebben geen gecentraliseerde middelen om de stroom van junkberichten tegen te gaan, en als de blockchain transacties van grote omvang en lage kosten ondersteunt, kan dit leiden tot het overbelasten van de transactiepool ā dit is weer een potentiĆ«le bottleneck voor de prestaties.
In blockchains, the client sends a transaction to any node in the blockchain that he likes; the transaction hash is usually known to the client even before sending, so all he needs to do is establish a connection and then wait for the blockchain to change its state by including his transaction. It is noted that measuring 'tps' can yield completely different results depending on the methods used to connect to a blockchain node. This can be a regular HTTP RPC or WebSocket, which allows implementing a 'subscribe' pattern. In the latter case, the client will receive notifications sooner, and the node will use fewer resources (mainly memory and bandwidth) for responses about the transaction status. Therefore, when measuring 'tps', the method of client connections to nodes must be taken into account. Thus, to evaluate the risks of this bottleneck, the blockchain benchmark should be able to simulate clients with both WebSocket and HTTP RPC requests, in proportions corresponding to real networks, as well as change the nature and size of transactions.
To assess the risks of this bottleneck, it is also necessary to collect metrics from client machines, not just from blockchain nodes.
Transaction and block transmission over a p2p network
In blockchains, peer-to-peer (p2p) networking is used to transmit transactions and blocks among participants. Transactions are spread across the network starting from one of the nodes until they reach peers-block producers who bundle transactions into blocks and distribute the new blocks to all nodes in the network via the same p2p process. The basis of most modern p2p networks is various modifications of the Kademlia protocol. a good brief overview of this protocol, and ā an article with various measurements in the BitTorrent network, from which it can be understood that this type of network is more complex and less predictable than a rigidly configured centralized service network. Also, an article on measuring various interesting metrics for Ethereum nodes.
In het kort, elke peer in dergelijke netwerken onderhoudt zijn eigen dynamische lijst van andere peers, waarvan hij blokken informatie aanvraagt die op inhoud zijn gericht. Bij ontvangst van een verzoek geeft de peer ofwel de benodigde informatie, of hij draagt het verzoek over aan de volgende pseudo-willekeurige peer in de lijst. Na het ontvangen van een antwoord, geeft hij dit door aan de aanvraager en cachet hij het gedurende enige tijd, zodat hij deze informatie bij de volgende keer eerder kan aanbieden. Op deze manier komt populaire informatie in veel caches van een groot aantal peers terecht, terwijl impopulaire informatie geleidelijk wordt verdrongen. Peers houden bij hoeveel informatie ze aan elkaar hebben doorgegeven, en het netwerk probeert actieve aanbieders te stimuleren door hun ranking te verhogen en hen een hoger serviceniveau te bieden, terwijl het tegelijkertijd inactieve deelnemers automatisch uit de peerslijsten verwijdert.
Dus de transactie moet nu door het netwerk worden verspreid, zodat block producers deze kunnen zien en in een blok kunnen opnemen. De node 'deelt' actief de nieuwe transactie met iedereen en luistert naar het netwerk, wachtend op een blok waarin de gewenste transactie zal verschijnen, om de wachtende klant te informeren. De tijd dat het netwerk informatie over nieuwe transacties en blokken uitwisselt in p2p-netwerken is afhankelijk van een groot aantal factoren: de hoeveelheid eerlijke, goed functionerende nodes in de buurt (vanuit een netwerkstandpunt), de 'opwarming' van de caches van deze nodes, de grootte van de blokken, transacties, de aard van de wijzigingen, de geografische spreiding van het netwerk, het aantal nodes en nog veel meer factoren. Complexe metingen van prestatiestatistieken in dergelijke netwerken zijn uitdagend; het is noodzakelijk om tegelijkertijd de verwerkingstijd van verzoeken zowel op clients als op peers (blockchain nodes) te evalueren. Problemen in een van de p2p-mechanismen, onjuiste verdringing en caching van gegevens, inefficiënt beheer van lijsten met actieve peers, en vele andere factoren kunnen vertragingen veroorzaken die de effectiviteit van het hele netwerk beïnvloeden, en deze bottleneck is het moeilijkst te analyseren, te testen en de resultaten te interpreteren.
Verwerking van de keten van blokken en bijwerking van de state database
Het belangrijkste onderdeel van de blockchain-werking is het consensusalgoritme, de toepassing ervan op nieuwe blokken verkregen uit het netwerk en de verwerking van transacties met registratie van resultaten in de state database. Het toevoegen van een nieuw blok aan de keten en de daaropvolgende keuze van de hoofdketen moet zo snel mogelijk plaatsvinden. In de praktijk betekent 'moet' echter niet altijd 'werkt', en men kan zich bijvoorbeeld een situatie voorstellen waarin twee lange concurrerende ketens voortdurend met elkaar schakelen, waardoor de metadata van duizenden transacties in de pool bij elke schakeling verandert, en voortdurend het staat van de state database teruggezet wordt. Deze fase, als het gaat om het bepalen van de bottleneck, is eenvoudiger dan de netwerk p2p laag, omdat de uitvoering van transacties en het consensusalgoritme strikt deterministisch zijn, en het meten van iets hier eenvoudiger is.
Het belangrijkste is om de toevallige degradatie van de prestaties in deze fase niet te verwarren met netwerproblemen ā de nodes leveren blokken en informatie over de hoofdketen trager, wat voor de externe klant kan overkomen als een langzaam netwerk, terwijl het probleem heel ergens anders ligt.
Voor prestatieoptimalisatie in deze fase is het nuttig om metrics van de nodes zelf te verzamelen en te monitoren, en deze op te nemen, waaronder die welke betrekking hebben op de update van de state-database: het aantal blokken dat op de node wordt verwerkt, hun grootte, het aantal transacties, het aantal schakelacties tussen fork-ketens, het aantal ongeldige blokken, de verwerkingstijd van de virtuele machine, de tijd om gegevens vast te leggen, enzovoort. Dit helpt om netwerkproblemen niet te verwarren met fouten in de algoritmes voor ketenverwerking.
De virtuele machine die transacties verwerkt kan een waardevolle informatiebron zijn om de blockchain-prestaties te optimaliseren. Het aantal geheugenallocaties, het aantal read/write-instructies, en andere metrics die betrekking hebben op de efficiƫntie van het uitvoeren van contractcode kunnen veel nuttige informatie bieden aan ontwikkelaars. Tegelijkertijd zijn smart contracts programma's, wat betekent dat ze in theorie elk van de middelen kunnen verbruiken: cpu/memory/network/storage, dus de verwerking van transacties is een vrij onbepaald stadium dat bovendien sterk verandert bij de overgang tussen versies en bij het aanpassen van contractcode. Daarom zijn metrics met betrekking tot transactieverwerking ook nodig voor effectieve optimalisatie van de blockchain-prestaties.
De notificatie van de klant over het inschakelen van de transactie in de blockchain
Dit is de laatste fase van het ontvangen van de service van de blockchain door de klant. In vergelijking met andere fasen zijn er hier geen hoge overheadkosten, maar het is nog steeds belangrijk om rekening te houden met de mogelijkheid dat de klant een omvangrijk antwoord van de node ontvangt (bijvoorbeeld een smart contract dat een array van gegevens retourneert). Hoe dan ook, dit is het moment dat het meest belangrijk is voor degene die de vraag heeft gesteld: 'hoeveel tps heeft uw blockchain?', aangezien op dit moment de tijd van de service ontvangen wordt.
Op dit punt moet de volledige tijd die de klant heeft besteed aan het wachten op een antwoord van de blockchain, worden verzonden. Dit is namelijk de tijd die de gebruiker zal verwachten voor bevestiging in zijn applicatie, en het optimaliseren daarvan is de belangrijkste taak voor ontwikkelaars.
Conclusie
Als resultaat kunnen we de typen operaties die in blockchains worden uitgevoerd beschrijven en deze in verschillende categorieƫn indelen:
- cryptografische transformaties, opbouw van bewijzen
- peer-to-peer netwerken, replicatie van transacties en blokken
- verwerking van transacties, uitvoering van smart contracts
- toepassing van wijzigingen in de blockchain op de state database, bijwerken van gegevens over transacties en blokken
- read-only aanvragen aan de state database, API van de blockchain node, abonnementsdiensten
Over het algemeen zijn de technische vereisten voor nodes van moderne blockchains zeer ernstig: dit zijn snelle CPU's voor cryptografie, veel RAM om de state database op te slaan en er snel toegang toe te krijgen, netwerkinfrastructuur die een groot aantal gelijktijdig open verbindingen ondersteunt, omvangrijke opslag. Deze hoge eisen en de overvloed aan verschillende soorten operaties leiden er onvermijdelijk toe dat de nodes mogelijk niet genoeg middelen hebben, en dan kan elke van de hierboven besproken fasen een bottleneck worden voor de algehele netwerkprestaties.
Bij het ontwikkelen en evalueren van de prestaties van blockchain-systemen moet u al deze aspecten in overweging nemen. Hiervoor is het nodig om tegelijkertijd metrics van zowel klanten als netwerk knooppunten te verzamelen en te analyseren, correlaties tussen deze metrics te zoeken, de responstijd naar klanten te evalueren en rekening te houden met alle belangrijke middelen: cpu/memory/netwerk/opslag. U moet begrijpen hoe deze middelen worden gebruikt en elkaar beïnvloeden. Dit maakt het vergelijken van de snelheden van verschillende blockchains in termen van 'hoeveel TPS' een zeer dankeloze taak, omdat er een enorme verscheidenheid aan configuraties en toestanden bestaat. In grote gecentraliseerde systemen, clusters van honderden servers, zijn deze problemen ook complex en vereisen ze ook het verzamelen van een groot aantal verschillende metrics. Maar in blockchains, vanwege p2p-netwerken, virtuele machines, die contracten verwerken, en interne economieën, is het aantal vrijheidsgraden veel groter, waardoor testen op zelfs enkele servers niet representatief is en slechts zeer grove waarden laat zien die bijna geen verband houden met de werkelijkheid.
Daarom gebruiken we bij het ontwikkelen van de blockchain-kernel, om de prestaties te evalueren en te beantwoorden op de vraag 'is het beter dan de vorige keer', behoorlijk complexe software die de lancering van de blockchain met tientallen knooppunten orkestreert en automatisch benchmarks en metrics verzamelt. Zonder deze informatie is het uiterst moeilijk om protocollen te debuggen die met een groot aantal deelnemers werken.
Dus, als u de vraag krijgt 'hoeveel TPS heeft uw blockchain?', bied dan uw gesprekspartner een kopje thee aan en vraag of hij bereid is om een tiental grafieken te bekijken, evenals al uw voorstellen over de drie doos vol prestatieproblemen van blockchains en hoe deze op te lossen...
Bron: habr.com
