Die liebste Frage eines nicht-technischen Spezialisten zu jedem verteilten System lautet: „Wie viele TPS hat Ihre Blockchain?“. Allerdings hat die Zahl, die als Antwort genannt wird, normalerweise wenig mit dem zu tun, was der Fragesteller hören möchte. Tatsächlich wollte er fragen: „Eignet sich Ihre Blockchain für meine geschäftlichen Anforderungen?“, und diese Anforderungen sind keine einzelne Zahl, sondern eine Vielzahl von Bedingungen - hierzu gehören die Ausfallsicherheit des Netzwerks, Anforderungen an die Endgültigkeit, Größen, Charakter der Transaktionen und viele andere Parameter. Daher wird die Antwort auf die Frage „Wie viele TPS?“ kaum einfach sein und fast nie vollständig. Ein verteiltes System mit Dutzenden und Hunderten von Knoten, die recht komplexe Berechnungen durchführen, kann sich in einer riesigen Anzahl verschiedener Zustände befinden, die mit dem Zustand des Netzwerks, dem Inhalt der Blockchain, technischen Ausfällen, wirtschaftlichen Problemen, Angriffen auf das Netzwerk und vielen anderen Gründen verbunden sind. Die Phasen, in denen Leistungsprobleme auftreten können, unterscheiden sich von den traditionellen Diensten, und der Server eines Blockchain-Netzwerks ist ein Netzwerkdienst, der die Funktionen einer Datenbank, eines Webservers und eines Torrent-Clients kombiniert, was ihn in Bezug auf das Lastprofil für alle Subsysteme - Prozessor, Speicher, Netzwerk, Speicher - äußerst komplex macht.
Es hat sich ergeben, dass dezentrale Netzwerke und Blockchains eine ziemlich spezielle und ungewohnte Software für Entwickler zentralisierter Software sind. Daher möchte ich wichtige Aspekte der Leistung und Stabilität dezentraler Netzwerke, Ansätze zu deren Messung und Ermittlung von Engpässen beleuchten. Wir werden verschiedene Leistungsprobleme betrachten, die die Geschwindigkeit der Bereitstellung von Dienstleistungen an Benutzer von Blockchains einschränken, und die Merkmale hervorheben, die für diese Art von Software typisch sind.
Phasen der Diensteanforderung durch den Blockchain-Client
Um ehrlich über die Qualität eines mehr oder weniger komplexen Dienstes zu sprechen, müssen nicht nur Durchschnittswerte, sondern auch Maximal-/Minimalwerte, Mediane und Perzentile berücksichtigt werden. Theoretisch kann man von 1000 tps in irgendeiner Blockchain sprechen, aber wenn 900 Transaktionen mit großer Geschwindigkeit erfolgreich waren und 100 - "hängen geblieben" sind für einige Sekunden, dann ist die durchschnittliche Zeit, die über alle Transaktionen erfasst wurde, nicht wirklich eine faire Metrik für den Kunden, der sein Geschäft nicht in wenigen Sekunden abschließen konnte. Zeitliche "Löcher", die durch versäumte Konsens-Runden oder durch Netzwerk-Trennungen verursacht werden, können den Dienst stark beeinträchtigen, der auf Test-Benchmarks eine hervorragende Leistung gezeigt hat.
Um solche Engpässe zu identifizieren, ist es notwendig, die Phasen gut zu verstehen, in denen eine echte Blockchain Schwierigkeiten bei der Bedienung der Benutzer haben kann. Lassen Sie uns den Lieferservice- und Verarbeitungszyklus von Transaktionen sowie den Erhalt eines neuen Zustands der Blockchain beschreiben, aus dem der Kunde bestätigen kann, dass seine Transaktion verarbeitet und erfasst wurde.
- Die Transaktion wird auf dem Client erstellt
- Die Transaktion wird auf dem Client signiert
- Der Client wählt einen der Knoten und sendet seine Transaktion an ihn
- Der Client abonniert die Updates der State-Datenbank des Knotens und wartet auf das Ergebnis der Ausführung seiner Transaktion
- Der Knoten verbreitet die Transaktion im P2P-Netzwerk
- Einige oder ein Blockproduzent (BP) verarbeitet die gesammelten Transaktionen und aktualisiert die State-Datenbank
- Der BP erstellt einen neuen Block, indem er die erforderliche Anzahl von Transaktionen verarbeitet
- Der BP verbreitet den neuen Block im P2P-Netzwerk
- Der neue Block wird an den Knoten geliefert, auf den der Client zugreift
- Der Knoten aktualisiert die State-Datenbank
- Der Knoten sieht das Update bezüglich des Clients und sendet ihm eine Benachrichtigung über die Transaktion
Jetzt lassen Sie uns diese Phasen genauer betrachten und die potenziellen Leistungsprobleme in jeder Phase beschreiben. Im Gegensatz zu zentralisierten Systemen werden wir auch die Ausführung des Codes auf den Clients im Netzwerk betrachten. Oft wird beim Messen von TPS die Verarbeitungszeit von Transaktionen von Knoten und nicht vom Client erfasst – das ist nicht ganz fair. Es interessiert den Client nicht, wie schnell der Knoten seine Transaktion verarbeitet hat; das Wichtigste für ihn ist der Moment, in dem ihm die verifizierte Information über diese Transaktion, die in die Blockchain aufgenommen wurde, zur Verfügung steht. Diese Metrik ist im Grunde die Ausführungszeit der Transaktion. Das bedeutet, dass verschiedene Clients, selbst wenn sie dieselbe Transaktion senden, ganz unterschiedliche Zeiten erhalten können, die vom Kanal, der Auslastung und der Nähe des Knotens abhängen usw. Daher ist es unbedingt erforderlich, diese Zeit auf den Clients zu messen, da dieser Parameter optimiert werden muss.
Vorbereitung der Transaktion auf der Clientseite
Beginnen wir mit den ersten beiden Punkten: Die Transaktion wird vom Client erstellt und signiert. Merkwürdigerweise kann dies auch ein Engpass für die Leistung der Blockchain aus Sicht des Clients sein. Dies ist ungewohnt für zentralisierte Dienste, die alle Berechnungen und Datenoperationen für sich beanspruchen, während der Client einfach eine kurze Anfrage vorbereitet, die in der Lage ist, große Datenmengen oder Berechnungen anzufordern und das fertige Ergebnis zu erhalten. In Blockchains wird der Client-Code immer leistungsfähiger, während der Blockchain-Kern immer leichter wird, und umfangreiche Rechenaufgaben werden üblicherweise an die Client-Software übertragen. In Blockchains gibt es Clients, die eine Transaktion recht lange vorbereiten können (ich spreche von verschiedenen Merkle-Proofs, succinct proofs, threshold signatures und anderen komplexen Operationen auf der Clientseite). Ein gutes Beispiel für eine einfache On-Chain-Überprüfung und die anspruchsvolle Vorbereitung der Transaktion auf dem Client ist der Nachweis der Zugehörigkeit zu einer Liste basierend auf einem Merkle-Baum. .
Es ist auch wichtig zu beachten, dass der Client-Code nicht einfach Transaktionen an die Blockchain sendet, sondern zuerst den Zustand der Blockchain abfragt – und diese Aktivität kann die Auslastung des Netzwerks und der Blockchain-Knoten beeinflussen. Daher ist es sinnvoll, bei den Messungen das Verhalten des Client-Codes so genau wie möglich zu emulieren. Selbst wenn in Ihrer Blockchain übliche leichte Clients vorhanden sind, die eine normale digitale Signatur für eine einfache Transaktion zur Übertragung eines Vermögenswerts setzen, steigt mit jedem Jahr die Rechenleistung auf der Client-Seite an, die Kryptoalgorithmen werden robuster und dieser Teil der Verarbeitung könnte in der Zukunft zu einem erheblichen Engpass werden. Seien Sie also vorsichtig und übersehen Sie nicht, dass in einer Transaktion, die 3,5 Sekunden dauert, 2,5 Sekunden für die Vorbereitung und Unterzeichnung der Transaktion benötigt werden und 1,0 Sekunden für den Versand an das Netzwerk und das Warten auf eine Antwort. Um das Risiko eines solchen Engpasses zu bewerten, müssen Metriken von den Client-Maschinen gesammelt werden, nicht nur von den Blockchain-Knoten.
Übermittlung der Transaktion und Überwachung ihres Status
Der nächste Schritt besteht darin, die Transaktion an den gewählten Blockchain-Knoten zu senden und den Status ihrer Aufnahme in den Transaktionspool zu erhalten. Dieser Schritt ähnelt einem normalen Datenbankaufruf, der Knoten muss die Transaktion in den Pool einfügen und beginnen, Informationen darüber über das P2P-Netzwerk zu verbreiten. Der Ansatz zur Leistungsbewertung ist hier ähnlich wie bei der Bewertung der Funktionsweise traditioneller Microservices über Web-APIs, wobei die Transaktionen in den Blockchains aktualisiert werden können und aktiv ihren Status ändern. Tatsächlich kann die Aktualisierung von Informationen über eine Transaktion in einigen Blockchains mehrmals erfolgen, zum Beispiel beim Wechseln zwischen Forks der Kette oder wenn BP mitteilen, dass sie beabsichtigen, die Transaktion in einen Block aufzunehmen. Einschränkungen bei der Größe dieses Pools und der Anzahl der Transaktionen darin können die Leistung der Blockchain beeinflussen. Wenn der Transaktionspool auf die maximal mögliche Größe gefüllt ist oder nicht in den Arbeitsspeicher passt, kann die Netzwerkleistung stark sinken. Blockchains haben keine zentralisierten Mittel zum Schutz vor dem Fluss von Spam-Nachrichten, und wenn die Blockchain Transaktionen mit hohem Volumen und niedrigen Gebühren unterstützt, kann dies zu einer Überfüllung des Transaktionspools führen – dies ist ein weiterer potenzieller Engpass bei der Leistung.
In Blockchains sendet der Client die Transaktion an jeden beliebigen Knoten im Blockchain-Netzwerk. Der Hash der Transaktion ist dem Client meist bereits vor der Übertragung bekannt, sodass alles, was er benötigt, eine Verbindung herzustellen und dann auf die Änderung des Status der Blockchain zu warten, um seine Transaktion einzuschließen. Es sei darauf hingewiesen, dass bei der Messung von "tps" vollkommen unterschiedliche Ergebnisse für verschiedene Anschlussmethoden an Knoten im Blockchain-Netzwerk erzielt werden können. Dies kann entweder über reguläres HTTP RPC oder WebSocket erfolgen, die das "subscribe"-Muster ermöglichen. Im zweiten Fall erhält der Client eine frühere Benachrichtigung, und der Knoten benötigt weniger Ressourcen (hauptsächlich Speicher und Datenverkehr) für die Antworten zum Status der Transaktion. Daher ist es notwendig, die Art der Verbindung der Clients zu den Knoten bei der Messung von "tps" zu berücksichtigen. Daher muss der Benchmark der Blockchain in der Lage sein, Clients sowohl mit WebSocket- als auch HTTP RPC-Anfragen emulieren zu können, in Anteilen, die den realen Netzwerken entsprechen, sowie die Art der Transaktionen und deren Größe zu variieren.
Um die Risiken des Auftretens dieses Bottleneck zu bewerten, müssen auch Metriken von den Client-Maschinen gesammelt werden, und nicht nur von den Blockchain-Knoten.
Übertragung von Transaktionen und Blöcken über ein p2p-Netzwerk
In Blockchains wird zur Übertragung von Transaktionen und Blöcken zwischen den Teilnehmern eine Peer-to-Peer (p2p) Netzwerkarchitektur verwendet. Transaktionen verbreiten sich im Netzwerk, beginnend von einem der Knoten, bis sie die Peer-Blockproduzenten erreichen, die die Transaktionen in Blöcke verpacken und über dasselbe p2p-Netzwerk die neuen Blöcke an alle Knoten im Netzwerk verbreiten. Die Grundlage der meisten modernen p2p-Netze sind verschiedene Modifikationen des Kademlia-Protokolls. eine gute kurze Übersicht über dieses Protokoll, und — ein Artikel mit verschiedenen Messungen im BitTorrent-Netzwerk, aus dem man erkennen kann, dass diese Art von Netzwerken komplexer und weniger vorhersehbar ist als ein starr konfiguriertes Netzwerk eines zentralisierten Dienstes. Außerdem, ein Artikel über die Messung verschiedener interessanter Metriken für Ethereum-Knoten.
Kurz gesagt, jeder Peer in solchen Netzwerken führt seine eigene dynamische Liste von anderen Peers, von denen er Informationsblöcke anfordert, die nach ihrem Inhalt adressiert sind. Bei Eingang 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 für eine Weile im Cache, sodass er diesen Block bei der nächsten Anfrage schneller bereitstellen kann. Dadurch befindet sich beliebte Information in einem großen Anteil der Caches vieler Peers, während unpopuläre Informationen allmählich verdrängt werden. Peers halten darüber Buch, wer wie viel Informationen übermittelt hat, und das Netzwerk versucht, aktive Geber zu belohnen, indem es ihre Bewertung erhöht und ihnen einen höheren Service-Level bieten, während inaktive Teilnehmer automatisch aus den Peerl Listen entfernt werden.
Die Transaktion muss nun im Netzwerk verbreitet werden, damit sie von den Blockproduzenten gesehen und in einen Block aufgenommen wird. Der Knoten gibt die neue Transaktion aktiv an alle Interessierten weiter und hört im Netzwerk nach, während er auf einen Block wartet, in dessen Index die benötigte Transaktion erscheint, um den wartenden Kunden zu benachrichtigen. Die Zeit, die das Netzwerk benötigt, um Informationen über neue Transaktionen und Blöcke in P2P-Netzwerken auszutauschen, hängt von einer sehr großen Anzahl von Faktoren ab: der Anzahl der ehrlichen, benachbarten Knoten (aus Netzwerkperspektive), der „Eingewöhnung“ der Caches dieser Knoten, der Blockgrößen, der Transaktionen, der Art der Veränderungen, der Geografie des Netzwerks, der Anzahl der Knoten und vielen weiteren Faktoren. Komplexe Messungen der Leistungsmetriken in solchen Netzwerken sind eine schwierige Angelegenheit; es ist notwendig, gleichzeitig die Bearbeitungszeit von Anfragen sowohl auf den Clients als auch auf den Peers (Blockchain-Knoten) zu bewerten. Probleme in einem der P2P-Mechanismen, fehlerhafte Cache-Ausräumung und -Speicherung von Daten, ineffizientes Management aktiver Peers und viele andere Faktoren können zu Verzögerungen führen, die die Effizienz des gesamten Netzwerks beeinträchtigen, und dieser Engpass ist am schwierigsten zu analysieren, zu testen und die Ergebnisse zu interpretieren.
Verarbeitung der Blockkette und Aktualisierung der Statusdatenbank
Der wichtigste Teil der Blockhain-Arbeit ist der Konsensalgorithmus, seine Anwendung auf neue, aus dem Netzwerk erhaltene Blöcke und die Verarbeitung von Transaktionen mit der Aufzeichnung der Ergebnisse in der Zustandsdatenbank. Das Hinzufügen eines neuen Blocks zur Kette und die anschließende Wahl der Hauptkette sollten möglichst schnell erfolgen. In der realen Welt bedeutet jedoch "sollten" nicht unbedingt "funktioniert", und man kann sich beispielsweise eine Situation vorstellen, in der zwei lange konkurrierende Ketten ständig zwischen einander umschalten, wodurch die Metadaten von Tausenden von Transaktionen im Pool bei jedem Umschalten verändert werden und es zu ständigen Rückführungen des Status der Zustandsdatenbank kommt. Dieser Schritt ist in Bezug auf die Identifizierung des Flaschenhalses einfacher als die P2P-Netzwerkschicht, da die Ausführung von Transaktionen und der Konsensalgorithmus streng deterministisch sind, und es einfacher ist, hier etwas zu messen.
Es ist wichtig, zufällige Leistungseinbußen in diesem Abschnitt nicht mit Netzwerkproblemen zu verwechseln — Knoten geben Blöcke und Informationen über die Hauptkette langsamer weiter, was für den externen Kunden wie ein langsames Netzwerk erscheinen kann, obwohl das Problem ganz woanders liegt.
Zur Optimierung der Leistung in diesem Abschnitt ist es nützlich, Metriken von den Knoten zu sammeln und zu überwachen, einschließlich derjenigen, die sich auf die Aktualisierung der Zustandsdatenbank beziehen: die Anzahl der Blöcke, die auf dem Knoten verarbeitet werden, ihre Größe, die Anzahl der Transaktionen, die Anzahl der Umschaltungen zwischen Ketten-Forks, die Anzahl der ungültigen Blöcke, die Laufzeit der virtuellen Maschine, die Zeit zur Datenspeicherung usw. Dies ermöglicht es, Netzwerkprobleme nicht mit Fehlern in den Algorithmen der Kettenverarbeitung zu verwechseln.
Die mit der Verarbeitung von Transaktionen befasste virtuelle Maschine kann eine nützliche Informationsquelle sein, um die Funktionalität der Blockchain zu optimieren. Die Anzahl der Speicherzuweisungen, die Anzahl der Lese-/Schreiboperationen und andere Metriken zur Effizienz der Codeausführung von Verträgen können den Entwicklern viele nützliche Informationen liefern. Gleichzeitig sind Smart Contracts Programme, was bedeutet, dass sie theoretisch jegliche Ressourcen verbrauchen können: CPU/Speicher/Netzwerk/Speicher, sodass die Verarbeitung von Transaktionen ein recht unbestimmter Schritt ist, der sich zudem stark verändert, wenn zwischen Versionen gewechselt wird und sich der Code der Verträge ändert. Daher sind Metriken zur Verarbeitung von Transaktionen auch für eine effektive Leistungsoptimierung der Blockchain erforderlich.
Benachrichtigung des Kunden über die Aktivierung der Transaktion in der Blockchain
Dies ist die abschließende Phase des Dienstes, den der Kunde von der Blockchain erhält. Im Vergleich zu anderen Phasen gibt es hier keine hohen Gemeinkosten, dennoch sollte die Möglichkeit, dass der Kunde eine umfangreiche Antwort von der Node erhält (z. B. ein Smart Contract, der ein Datenarray zurückgibt), berücksichtigt werden. In jedem Fall ist dieser Moment der wichtigste für diejenigen, die die Frage "Wie viele TPS hat Ihre Blockchain?" gestellt haben, da hier die Zeit für den Erhalt des Dienstes erfasst wird.
An diesem Punkt ist es unbedingt erforderlich, die gesamte Zeit zu übermitteln, die der Kunde für das Warten auf die Antwort der Blockchain aufwenden musste. Diese Zeit wird der Benutzer in seiner Anwendung als Bestätigung erwarten, und die Optimierung dieser Zeit ist die Hauptaufgabe der Entwickler.
Fazit
Infolgedessen können die in Blockchains ausgeführten Operationstypen beschrieben und in mehrere Kategorien unterteilt werden:
- kryptographische Umwandlungen, Aufbau von Nachweisen
- Peer-to-Peer-Netzwerke, Replikation von Transaktionen und Blöcken
- Verarbeitung von Transaktionen, Ausführung von Smart Contracts
- Anwendung von Änderungen in der Blockchain an der Zustandsdatenbank, Aktualisierung der Transaktions- und Blockdaten
- Read-Only-Anfragen an die Zustandsdatenbank, API der Blockchain-Node, Abonnementdienste
Die technischen Anforderungen an die Nodes moderner Blockchains sind insgesamt äußerst anspruchsvoll — schnelle CPUs für die Kryptografie, viel Arbeitsspeicher, um die Zustandsdatenbank zu speichern und schnell darauf zuzugreifen, Netzwerkinteraktionen mit einer großen Anzahl gleichzeitig geöffneter Verbindungen und umfangreicher Speicherplatz. Solche hohen Anforderungen und die Vielzahl verschiedener Operationstypen führen unvermeidlich dazu, dass die Ressourcen der Nodes möglicherweise nicht ausreichen und jeder der zuvor behandelten Schritte zum Bottleneck der Gesamtleistung des Netzwerks werden kann.
Bei der Entwicklung und Bewertung der Leistung von Blockchains müssen Sie all diese Aspekte berücksichtigen. Dazu ist es notwendig, Metriken gleichzeitig von Clients und Knoten im Netzwerk zu sammeln und zu analysieren, Korrelationen zwischen ihnen zu suchen, die Antwortzeit für die Bereitstellung von Diensten an Kunden zu bewerten, alle Hauptressourcen zu berücksichtigen: CPU/Memory/Netzwerk/Speicher, und zu verstehen, wie sie genutzt werden und sich gegenseitig beeinflussen. All dies macht den Vergleich der Geschwindigkeiten verschiedener Blockchains in Form von „wie viel TPS“ zu einer ganz und gar undankbaren Aufgabe, da es eine enorme Anzahl verschiedener Konfigurationen und Zustände gibt. In großen zentralisierten Systemen, Clustern mit Hunderten von Servern, sind diese Probleme ebenfalls komplex und erfordern ebenfalls das Sammeln einer Vielzahl unterschiedlicher Metriken. Aber bei Blockchains, aufgrund von P2P-Netzwerken, virtuellen Maschinen, die Verträge verarbeiten, und interner Ökonomie, ist die Anzahl der Freiheitsgrade wesentlich höher, was selbst den Test auf mehreren Servern unzuverlässig macht und nur extrem ungefähre Werte anzeigt, die kaum mit der Realität zu tun haben.
Deshalb verwenden wir bei der Entwicklung im Kern der Blockchain zur Leistungsbewertung und zur Beantwortung der Frage „Hat es sich im Vergleich zum letzten Mal verbessert?“ eine ziemlich komplexe Software, die den Start der Blockchain mit Dutzenden von Knoten orchestriert und den Benchmark zusammen mit dem Sammeln von Metriken automatisch startet. Ohne diese Informationen ist es extrem schwierig, Protokolle zu debuggen, die mit vielen Teilnehmern arbeiten.
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 sowie sämtliche drei Kisten der Leistungsprobleme von Blockchains und Ihre Vorschläge zu deren Lösung anzuhören...
Quelle: habr.com
