Eine häufige Frage von Nicht-Technikern zu verteilten Systemen lautet: „Wie viele TPS hat Ihre Blockchain?“ Allerdings hat die genannte Zahl häufig wenig mit dem zu tun, was der Fragesteller tatsächlich hören möchte. In Wahrheit wollte er fragen: „Entspricht Ihre Blockchain meinen Geschäftsanforderungen?“ Diese Anforderungen sind kein einzelner Wert, sondern eine Vielzahl von Bedingungen – dazu gehören die Ausfallsicherheit des Netzwerks, die Anforderungen an die Endgültigkeit, die Größe, die Art der Transaktionen und viele andere Parameter. Daher wird die Antwort auf die Frage „Wie viele TPS?“ wahrscheinlich nicht einfach sein und fast nie vollständig. Ein verteiltes System mit Dutzenden oder Hunderten von Knoten, die ziemlich komplexe Berechnungen durchführen, kann sich in unzähligen verschiedenen Zuständen befinden, die mit dem Zustand des Netzwerks, dem Inhalt der Blockchain, technischen Störungen, wirtschaftlichen Problemen, Angriffen auf das Netzwerk und vielen anderen Gründen verbunden sind. Die Phasen, in denen Leistungsprobleme möglich sind, unterscheiden sich von traditionellen Diensten, während ein Server des Blockchain-Netzwerks einen Netzwerkdienst darstellt, der die Funktionalitäten einer Datenbank, eines Webservers und eines Torrent-Clients kombiniert, was ihn in Bezug auf das Lastprofil für alle Subsysteme – Prozessor, Arbeitsspeicher, Netzwerk, Speicher – äußerst komplex macht.
Dezentralisierte Netzwerke und Blockchains sind für Entwickler zentralisierter Software oft neu und speziell. Daher möchte ich wichtige Aspekte der Leistung und Stabilität dezentralisierter Netzwerke beleuchten, sowie Ansätze zu deren Messung und zur Identifizierung von Engpässen. Wir werden verschiedene Leistungsprobleme behandeln, die die Geschwindigkeit der Servicebereitstellung für Blockchain-Nutzer einschränken, und die spezifischen Eigenschaften dieser Art von Software hervorheben.
Phasen der Serviceanfrage durch den Blockchain-Kunden
Um ehrlich über die Qualität eines komplexen Dienstes zu sprechen, müssen nicht nur die Durchschnittswerte, sondern auch die maximalen/mindesten Werte, Mediane und Perzentile berücksichtigt werden. Theoretisch kann man von 1000 TPS in einer Blockchain sprechen, aber wenn 900 Transaktionen blitzschnell durchgeführt werden und 100 Transaktionen mehrere Sekunden „hängen bleiben“, dann ist die Durchschnittszeit für alle Transaktionen keine ehrliche Metrik für den Kunden, der seine Transaktion innerhalb weniger Sekunden nicht abschließen konnte. Temporäre „Löcher“, verursacht durch verpasste Konsensrunden oder Netzwerktrennungen, können den Dienst stark beeinträchtigen, der in Testumgebungen hervorragende Leistung gezeigt hat.
Um solche Engpässe zu identifizieren, ist es wichtig, die Phasen zu verstehen, in denen eine echte Blockchain Schwierigkeiten haben könnte, Benutzer zu bedienen. Lassen Sie uns den Liefervorgang und den Prozess der Verarbeitung von Transaktionen sowie den Erhalt des neuen Status der Blockchain beschreiben, aus dem der Kunde ersehen kann, dass seine Transaktion verarbeitet und berücksichtigt wurde.
- Die Transaktion wird auf dem Client erstellt
- Die Transaktion wird auf dem Client signiert
- Der Kunde wählt einen der Nodes aus und sendet seine Transaktion dorthin.
- Der Kunde abonniert die Aktualisierungen der State-Datenbank des Nodes und wartet auf die Ergebnisse der Ausführung seiner Transaktion.
- Der Node verbreitet die Transaktion im P2P-Netzwerk.
- Mehrere oder ein Blockproduzent (BP) verarbeiten die gesammelten Transaktionen und aktualisieren die State-Datenbank.
- Der BP bildet einen neuen Block, indem er die erforderliche Anzahl an Transaktionen verarbeitet.
- Der BP verbreitet den neuen Block im P2P-Netzwerk.
- Der neue Block wird dem Node zugestellt, mit dem der Kunde sich verbindet.
- Der Node aktualisiert die State-Datenbank.
- Der Node sieht das Update, das den Kunden betrifft, und sendet ihm eine Benachrichtigung über die Transaktion.
Lassen Sie uns nun diese Schritte genauer betrachten und potenzielle Leistungsprobleme in jedem Schritt beschreiben. Im Gegensatz zu zentralisierten Systemen werden wir auch die Ausführung von Code auf den Clients im Netzwerk betrachten. Oft wird bei der Messung der TPS die Verarbeitungszeit von Transaktionen von den Nodes erfasst und nicht vom Client – das ist nicht ganz fair. Den Clients ist es egal, wie schnell die Node ihre Transaktion verarbeitet hat; das Wichtigste für sie ist der Moment, in dem die verlässliche Information über diese Transaktion, die im Blockchain enthalten ist, für sie verfügbar wird. Genau diese Metrik ist im Grunde die Ausführungszeit der Transaktion. Das bedeutet, dass verschiedene Clients, selbst wenn sie die gleiche Transaktion senden, völlig unterschiedliche Zeiten erhalten können, die von Faktoren wie dem Kanal, der Auslastung und der Nähe der Node abhängen, usw. Daher ist es unerlässlich, diese Zeit auf den Clients zu messen, da genau dieses Parameter optimiert werden muss.
Vorbereitung der Transaktion auf der Client-Seite
Lassen Sie uns mit den ersten beiden Punkten beginnen: Die Transaktion wird vom Kunden erstellt und signiert. Merkwürdigerweise kann dies auch ein Engpass in der Leistung der Blockchain aus der Sicht des Kunden sein. Dies ist für zentralisierte Dienste ungewohnt, die alle Berechnungen und Datenoperationen selbst übernehmen, während der Kunde nur eine kurze Anfrage vorbereitet, die große Datenmengen oder Berechnungen anfordern kann und ein fertiges Ergebnis erhält. In Blockchain-Systemen wird der Client-Code immer leistungsfähiger, während der Kern der Blockchain immer leichter wird. Massive Rechenaufgaben werden üblicherweise an die Client-Software delegiert. In Blockchains gibt es Clients, die eine einzelne Transaktion relativ lange vorbereiten können (ich spreche dabei von verschiedenen Merkle-Proofs, succinct proofs, threshold Signaturen und anderen komplexen Operationen auf der Client-Seite). Ein gutes Beispiel für eine unkomplizierte On-Chain-Verifizierung und die aufwendige Vorbereitung einer Transaktion auf der Client-Seite ist der Nachweis der Zugehörigkeit zu einer Liste auf Basis von Merkle-Bäumen. .
Sie sollten auch bedenken, dass der Client-Code nicht einfach Transaktionen an die Blockchain sendet, sondern zunächst den Zustand der Blockchain abruft – und diese Aktivität kann die Netzwerkauslastung und die Blockchain-Knoten beeinflussen. Daher ist es sinnvoll, bei Messungen das Verhalten des Client-Codes so vollständig wie möglich zu emulieren. Selbst wenn in Ihrer Blockchain gewöhnliche leichte Clients vorhanden sind, die bei einfachsten Transaktionen eine digitale Signatur für die Übertragung eines bestimmten Assets setzen, steigt die Anzahl der massiven Berechnungen auf dem Client mit jedem Jahr. Die Kryptographie wird robuster, und dieser Teil des Prozesses könnte in Zukunft zu einem signifikanten Engpass werden. Seien Sie also vorsichtig und übersehen Sie nicht, dass bei einer Transaktion von 3,5 Sekunden, 2,5 Sekunden für die Vorbereitung und Signatur der Transaktion und 1,0 Sekunden für die Übermittlung im Netzwerk und das Warten auf eine Antwort verwendet werden. Um die Risiken dieses Engpasses zu bewerten, müssen Sie Metriken von den Client-Maschinen sammeln, nicht nur von Blockchain-Knoten.
Transaktion senden und ihren Status überwachen
Der nächste Schritt besteht darin, die Transaktion an den ausgewählten Blockchain-Knoten zu senden und den Status ihrer Aufnahme in den Transaktionspool abzurufen. Dieser Schritt ähnelt einem herkömmlichen Datenbankaufruf: Der Knoten muss die Transaktion im Pool speichern und beginnen, Informationen darüber über das P2P-Netzwerk zu verbreiten. Der Ansatz zur Leistungsbewertung hier ähnelt der Bewertung der Leistung traditioneller Microservices im Web-API-Bereich, wobei die Transaktionen in Blockchain-Netzwerken aktualisiert und aktiv ihren Status ändern können. Tatsächlich kann die Aktualisierung von Informationen zu einer Transaktion in bestimmten Blockchains mehrere Male stattfinden, z.B. beim Umschalten zwischen Forks der Kette oder wenn BPs (Block Producer) ihre Absicht mitteilen, die Transaktion in einen Block aufzunehmen. Einschränkungen hinsichtlich des Volumens dieses Pools und der Anzahl der darin enthaltenen Transaktionen können sich auf die Leistung der Blockchain auswirken. Wenn der Transaktionspool auf die maximal mögliche Größe gefüllt ist oder nicht im Arbeitsspeicher Platz findet, kann die Netzwerkleistung erheblich sinken. Blockchains haben keine zentralen Schutzmechanismen gegen den Fluss von Spam-Nachrichten, und wenn die Blockchain Transaktionen mit hohem Volumen und niedrigen Gebühren unterstützt, kann dies zu einer Überlastung des Transaktionspools führen — dies ist ein weiterer potenzieller Engpass in der Performance.
In Blockchains sendet der Kunde eine Transaktion an einen beliebigen Knoten des Blockchain-Netzwerks. Der Hash der Transaktion ist dem Kunden in der Regel bereits vor der Übertragung bekannt, sodass er lediglich eine Verbindung herstellen und auf die Bestätigung warten muss, wenn die Blockchain ihren Zustand ändert und seine Transaktion integriert. Es ist anzumerken, dass die Messung von 'tps' verschiedene Ergebnisse für unterschiedliche Verbindungsarten zum Blockchain-Knoten liefern kann. Dies kann über das herkömmliche HTTP RPC oder WebSocket erfolgen, das das 'subscribe'-Muster ermöglicht. Im zweiten Fall erhält der Kunde die Benachrichtigung schneller, und der Knoten verbraucht weniger Ressourcen (hauptsächlich Speicher und Datenverkehr) für Antworten zum Transaktionsstatus. Daher sollte beim Messen von 'tps' die Art der Verbindung der Kunden zu den Knoten berücksichtigt werden. Um die Risiken eines Bottlenecks zu bewerten, sollte das Blockchain-Benchmarking in der Lage sein, sowohl Clients über WebSocket als auch über HTTP RPC-Anfragen zu emulieren, entsprechend den Anteilen realer Netzwerke, sowie die Art und Größe der Transaktionen zu variieren.
Zur Bewertung der Risiken eines Bottlenecks sollten auch Metriken von den Client-Maschinen und nicht nur von den Blockchain-Knoten gesammelt werden.
Übertragung von Transaktionen und Blöcken über das P2P-Netzwerk
In Blockchains wird für die Übertragung von Transaktionen und Blöcken zwischen den Teilnehmern ein Peer-to-Peer (P2P) Netzwerk verwendet. Transaktionen breiten sich im Netzwerk aus, beginnend mit einem der Knoten, bis sie die Peer-Blockproduzenten erreichen, die die Transaktionen in Blöcke bündeln und die neuen Blöcke mit dem gleichen P2P-Protokoll an alle Knoten im Netzwerk verteilen. Die Grundlage der meisten modernen P2P-Netzwerke sind verschiedene Modifikationen des Kademlia-Protokolls. eine gute kurze Übersicht über dieses Protokoll, sowie ein Artikel mit verschiedenen Messungen im BitTorrent-Netzwerk, der zeigt, dass dieser Netztyp komplexer und weniger vorhersehbar ist als ein starr konfiguriertes Netzwerk eines zentralisierten Dienstes. Darüber hinaus ein Artikel über die Messung verschiedener interessanter Metriken für Ethereum-Knoten.
Kurz gesagt unterstützt jeder Peer in solchen Netzwerken eine eigene dynamische Liste anderer Peers, von denen er Informationsblöcke anfordert, die nach Inhalt adressiert sind. Bei Erhalt einer Anfrage gibt der Peer entweder die benötigten Informationen weiter oder leitet die Anfrage an den nächsten pseudo-zufälligen Peer in der Liste weiter. Nach Erhalt der Antwort übermittelt er diese an den Anfragenden und speichert sie eine Zeit lang im Cache, sodass er den Informationsblock beim nächsten Mal schneller bereitstellen kann. So gelangt populäre Information in viele Caches über zahlreiche Peers, während weniger populäre Inhalte allmählich verdrängt werden. Die Peers führen Buch darüber, wie viel Information sie wem übermittelt haben, und das Netzwerk versucht, aktive Verteiler zu belohnen, indem es deren Rating erhöht und ihnen einen besseren Service-Level bietet, während inaktive Teilnehmer automatisch aus den Peer-Listen entfernt werden.
Um die Transaktion nun zu verbreiten, muss sie im Netzwerk sichtbar gemacht werden, damit sie von den Blockproduzenten gesehen und in einen Block aufgenommen wird. Der Knoten "verteilt" die neue Transaktion aktiv an alle Interessierten und hört gleichzeitig im Netzwerk auf, um den Block zu erwarten, in dem die angeforderte Transaktion erscheinen wird, um den wartenden Kunden zu benachrichtigen. Die Zeit, die benötigt wird, damit das Netzwerk Informationen über neue Transaktionen und Blöcke in P2P-Netzen austauscht, hängt von einer Vielzahl von Faktoren ab: der Anzahl der ehrlichen, dabei aktiven Knoten in der Nähe (aus der Sicht des Netzwerks), der "Wärmung" der Caches dieser Knoten, der Größe der Blöcke, der Transaktionen, der Art der Änderungen, der Geographie des Netzwerks, der Anzahl der Knoten und vieler weiterer Faktoren. Komplexe Messungen der Leistungsmetriken in solchen Netzwerken sind eine Herausforderung, da gleichzeitig die Bearbeitungszeiten sowohl für die Anfragen der Klienten als auch für die Peers (Blockchain-Knoten) bewertet werden müssen. Probleme in einem der P2P-Mechanismen, falsches Aggressiv-Laden und Caching von Daten, ineffizientes Management der Listen aktiver Peers und viele andere Faktoren können zu Verzögerungen führen, die die Effizienz des gesamten Netzwerks beeinflussen, und dieser Engpass ist der schwierigste zu analysieren, zu testen und die Ergebnisse zu interpretieren.
Die Verarbeitung von Blockchains und die Aktualisierung der Zustand-Datenbank
Der Algorithmus für den Konsens ist das Herzstück der Blockchain-Arbeit. Er wird auf die neuen, aus dem Netzwerk erhaltenen Blöcke angewendet und verarbeitet Transaktionen, indem die Ergebnisse in die Zustand-Datenbank geschrieben werden. Das Hinzufügen eines neuen Blocks zur Kette und die darauf folgende Auswahl der Hauptkette müssen so schnell wie möglich erfolgen. In der Realität bedeutet jedoch "muss" nicht immer "funktioniert", und man kann sich zum Beispiel eine Situation vorstellen, in der zwei lange konkurrierende Ketten ständig zwischen sich umschalten, während sie die Metadaten von Tausenden von Transaktionen im Pool bei jedem Wechsel ändern und fortlaufend den Zustand der Zustand-Datenbank zurücksetzen. In Bezug auf die Ermittlung des Bottlenecks ist dieser Schritt einfacher als die Netzwerk-P2P-Schicht, da die Durchführung von Transaktionen und der Konsensalgorithmus strikt deterministisch sind, was die Messung hier erheblich erleichtert.
Das Wichtigste ist, die zufällige Leistungsverschlechterung dieses Schrittes nicht mit Netzwerkproblemen zu verwechseln — Nodes geben Blocks und Informationen zur Hauptkette langsamer weiter, und für den externen Kunden kann dies wie ein langsames Netzwerk erscheinen, obwohl das Problem an einer ganz anderen Stelle liegt.
Zur Optimierung der Leistung ist es in diesem Stadium hilfreich, Metriken von den Knoten zu sammeln und zu überwachen. Dabei sollten auch die Metriken zur Aktualisierung der State-Datenbank einbezogen werden: die Anzahl der auf dem Knoten verarbeiteten Blöcke, deren Größe, die Anzahl der Transaktionen, die Häufigkeit von Fork-Wechseln, die Anzahl ungültiger Blöcke, die Laufzeit der virtuellen Maschine, die Dauer der Datenspeicherung usw. Dies hilft, Netzwerkprobleme nicht mit Fehlern im Chain-Processing-Algorithmus zu verwechseln.
Eine virtuelle Maschine zur Verarbeitung von Transaktionen kann eine nützliche Informationsquelle sein, die die Effizienz von Blockchain-Operationen optimiert. Die Menge der zugewiesenen Speicherkapazität, die Anzahl der Lese-/Schreibbefehle und andere Kennzahlen zur Effektivität der Ausführung von Vertragscodes können Entwicklern wertvolle Einblicke geben. Zugleich sind Smart Contracts Programme, was bedeutet, dass sie theoretisch jede Art von Ressourcen nutzen können: CPU, Speicher, Netzwerk und Speicherplatz. Daher ist die Verarbeitung von Transaktionen ein eher ungewisser Prozess, der zudem stark variieren kann, wenn zwischen Versionen gewechselt wird oder sich der Code der Verträge ändert. Folglich sind Kennzahlen zur Verarbeitung von Transaktionen ebenfalls erforderlich, um die Leistung des Blockchain-Systems effektiv zu optimieren.
Der Kunde erhält eine Benachrichtigung über die Aufnahme der Transaktion in die Blockchain
Dies ist die endgültige Phase, in der der Kunde den Blockchain-Service erhält. Im Vergleich zu anderen Phasen gibt es hier keine großen Overhead-Kosten, dennoch sollte die Möglichkeit berücksichtigt werden, dass der Kunde umfangreiche Antworten von der Node erhält (zum Beispiel einen Smart Contract, der ein Datenarray zurückgibt). In jedem Fall ist dieser Moment der entscheidende Punkt für alle, die die Frage stellen: „Wie viele TPS hat Ihre Blockchain?“, da zu diesem Zeitpunkt die Service-Zeit erfasst wird.
An dieser Stelle ist es wichtig, die gesamte Zeit zu erfassen, die der Kunde mit dem Warten auf eine Antwort von der Blockchain verbracht hat. Genau diese Zeit wird der Benutzer in seiner Anwendung auf die Bestätigung warten, und deren Optimierung ist die Hauptaufgabe der Entwickler.
Fazit
Infolgedessen können die Arten von Operationen, die in Blockchains ausgeführt werden, beschrieben und in mehrere Kategorien eingeteilt werden:
- Kryptografische Transformationen, Erstellung von Beweisen
- Peer-to-Peer-Netzwerke, Replikation von Transaktionen und Blöcken
- Verarbeitung von Transaktionen, Ausführung von Smart Contracts
- Anwendung von Änderungen in der Blockchain auf die Statusdatenbank, Aktualisierung der Daten zu Transaktionen und Blöcken
- read-only Anfragen an die Zustandsdatenbank, API der Blockchain-Knoten, Abonnementdienste
Die technischen Anforderungen an moderne Blockchain-Knoten sind insgesamt sehr hoch — hier sind schnelle CPUs für die Kryptografie erforderlich, viel Arbeitsspeicher, um die Zustandsdatenbank zu speichern und schnell darauf zuzugreifen, sowie ein Netzwerk, das eine große Anzahl gleichzeitig geöffneter Verbindungen unterstützt, und umfangreicher Speicher. Diese hohen Anforderungen und die Vielzahl verschiedener Operationstypen führen zwangsläufig dazu, dass die Ressourcen der Knoten nicht ausreichen, und dann kann jeder der oben genannten Schritte zum nächsten Flaschenhals für die Gesamtleistung des Netzwerks werden.
Bei der Entwicklung und Bewertung der Leistung von Blockchains müssen alle diese Aspekte berücksichtigt werden. Dazu gehört das gleichzeitige Sammeln und Analysieren von Metriken sowohl von Clients als auch von Knoten im Netzwerk, das Suchen nach Korrelationen zwischen ihnen, die Beurteilung der Bereitstellungszeit für die Kunden, sowie das Berücksichtigen aller wesentlichen Ressourcen: CPU/Speicher/Netzwerk/Speicherplatz. Es ist wichtig zu verstehen, wie sie genutzt werden und wie sie sich gegenseitig beeinflussen. All dies macht den Vergleich der Geschwindigkeiten verschiedener Blockchains in Form von ‚wie viele TPS‘ zu einer äußerst undankbaren Aufgabe, da es eine riesige Anzahl verschiedener Konfigurationen und Zustände gibt. In großen zentralisierten Systemen, die aus Hunderten von Servern bestehen, sind diese Probleme ebenfalls komplex und erfordern das Sammeln einer Vielzahl unterschiedlicher Metriken, jedoch in Blockchains aufgrund von P2P-Netzwerken, virtuellen Maschinen, die Verträge verarbeiten, und einer internen Wirtschaft, gibt es weitaus mehr Freiheitsgrade. Dies macht Tests selbst auf mehreren Servern nicht aussagekräftig und zeigt lediglich grobe Werte, die kaum mit der Realität übereinstimmen.
Daher verwenden wir bei der Entwicklung im Kern der Blockchain eine recht komplexe Software, die den Start der Blockchain mit Dutzenden von Knoten orchestriert, automatisierte Benchmarks durchführt und Metriken sammelt. Ohne diese Informationen ist es äußerst schwierig, Protokolle, die mit mehreren Teilnehmern arbeiten, zu debuggen.
Wenn Sie also die Frage "Wie viel TPS hat Ihre Blockchain?" erhalten, bieten Sie Ihrem Gesprächspartner einen Tee an und fragen Sie, ob er bereit ist, sich mit einem Dutzend Grafiken auseinanderzusetzen und allen drei Herausforderungen bezüglich der Leistungsprobleme von Blockchains und Ihren Vorschlägen zu deren Lösung zuzuhören...
Quelle: habr.com
