- Hallo. Ich bin Sasha, ich arbeite bei Yandex, seit drei Jahren entwickle ich einen L7 Load Balancer. Ich erzähle Ihnen von einer schnellen und einfachen Möglichkeit, Ihr Netzwerk zu beschleunigen. Wir beginnen mit der siebten Ebene, HTTP, und gehen zur vierten Ebene, TCP, über. Heute werden wir nur über diese beiden Ebenen sprechen und sie detailliert behandeln.
In den letzten acht Jahren habe ich mehr Backend-Entwicklungen durchgeführt, und höchstwahrscheinlich blieb mein Wissen in den ersten Versionen auf dem Niveau von AngularJS. Sie wissen wahrscheinlich besser als ich, wie das alles funktioniert. Sie haben bereits alles optimiert, alles komprimiert, und hier kann ich Ihnen nichts raten.
Ich kann Ihnen jedoch raten, wie Sie Ihr Netzwerk beschleunigen können, indem Sie den Server selbst und das Betriebssystem selbst optimieren.
Um etwas zu beschleunigen, benötigen Sie Metriken. In diesem Fall haben wir Folgendes verwendet: Die durchschnittliche Zeit bis zum ersten Byte zeigt uns, wie schnell die TCP-Schicht ist, und die zweite Metrik ist die Zeit, um HTML vom ersten Byte zu empfangen. Wir haben experimentiert, unsere Metriken gemessen und nach dem Einschalten von BBR lag unsere Beschleunigung bei etwa zehn Prozent.
Um zu verstehen, was zehn Prozent sind, wenden wir uns dem absoluten Wert zu, der 66 Millisekunden beträgt. Wenn Sie zu Ihrem bevorzugten Online-Multiplayer-Spiel wechseln, beträgt der Ping an westeuropäische Server ungefähr 60 bis 70 Millisekunden.
Wie es schnell geht
Alle unsere Server werden mithilfe von Fernsteuerungsprotokollen verwaltet, in diesem Fall SSH. Wenn Sie noch nicht auf SSH gestoßen sind, können Sie Ihren Systemadministrator bitten, Ihren Server zu konfigurieren. Ich werde Ihnen sagen, wie Sie ihn davon überzeugen können.
Was ist BBR? Dies ist einer der Algorithmen, mit denen wir steuern können, wie Pakete in das Netzwerk gelangen. Und es wird mit den folgenden zwei Parametern konfiguriert. Das erste ist, den Paketplaner auf FQ zu setzen, dann erkläre ich Ihnen, warum Sie FQ verwenden sollten. Die zweite ist die Einbeziehung der Überlastungskontrolle selbst, dh der BBR selbst.
Es scheint, dass wir hier enden könnten. Tatsächlich gibt es jedoch viele Fallstricke, und höchstwahrscheinlich aktiviert Ihr Systemadministrator nicht nur BBR auf dem Server. Deshalb werden wir weiter gehen.
HTTP / 2 und Multiplexing
Wir beginnen mit Level 7, HTTP, und arbeiten uns langsam nach unten, um unsere Protokolle zu überprüfen.
Wir beginnen mit unseren Browsern, mit denen wir jeden Tag interagieren. Wir sehen die Webentwicklerkonsole. Die Konsole hat ein interessantes Feld für uns - Protokoll.
In unserem Fall sind die Protokolle HTTP / 1 und HTTP / 2. Es gibt auch das HTTP / 3-Protokoll, das auf dem QUIC-Protokoll von Google basiert. Aber heute werden wir nicht darauf zurückkommen, da es sich in der Entwicklung befindet und noch nicht vollständig genehmigt ist. Kehren wir zu HTTP / 1 zurück.
Auf der Folie sehen wir das Wireshark-Dienstprogramm, mit dem wir unsere Pakete und die Art und Weise, wie wir mit dem Netzwerk interagieren, analysieren können. Wir sehen, dass ein Feld grün hervorgehoben ist. Dies ist unsere HTTP-Anfrage. Unten sehen wir die Bytes, wie sie im Netzwerk dargestellt werden.
Wie sieht HTTP / 1 im wirklichen Leben aus? Dies ist ein ziemlich einfaches Protokoll. Es ist vollständig textbasiert, dh wir schreiben einfach den Text und senden ihn an das Netzwerk. Unsere Zeichen sind mit speziellen Hexadezimalwerten codiert. Auf der rechten Seite befindet sich eine ASCII-Tabelle, ein kleines Stück, mit dem Sie navigieren können.
Wir haben den ersten Teil in Form von Überschriften, die durch die Zeichen "\ r \ n \ r \ n" von unserem Körper getrennt sind. Wir fordern hier nur eine reguläre Ressource mit der GET-Methode an, sodass diese Anfrage keinen Text enthält. Und wir sehen, dass die Bytes ungefähr ähnlich sind wie in der ASCII-Tabelle. Wir fordern eine Art JS an, eine Art Ressource. Es gibt auch einen Host-Header, der die Domain angibt, mit der wir gerade arbeiten. Und - einige zusätzliche Header. Sie können benutzerdefiniert sein, Sie können jede verwenden.
HTTP / 2 ist ein komplexeres Protokoll. Es ist binär und Frames sind die kleinste Einheit des Informationsaustauschs. Es gibt viele Sonderfälle, Sondertypen dieser Rahmen. Sie können auf der Folie sehen, dass sie hervorgehoben sind.
In der ersten Zeile können wir auch beobachten, dass zwei Frames gleichzeitig in ein Paket passen. Wir werden nicht im Detail darauf eingehen, welche Frames existieren, es gibt einige davon. In diesem Fall interessieren wir uns für den Header-Frame, da wir nur Ressourcen anfordern können. Ich war ein bisschen an der Entwicklung von Wireshark beteiligt und habe dazu beigetragen, es in diesem Bereich zu verbessern.
Wir können sehen, dass es eine Get-Anfrage gibt. Wir sehen, dass in der Mitte eine Textdarstellung dieser Get-Anfrage steht. In der rechten Spalte sehen wir jedoch nur ein ausgewähltes Byte, und es wird nur diese get-Methode sein. Als nächstes erkläre ich, warum dies geschieht.
Als nächstes haben wir den Pfad-Header, der den Pfad zur Ressource angibt, zu unserem JS, den wir anfordern werden. Und es gibt eine Reihe zusätzlicher Header, die auch in unserer Anfrage enthalten sein werden.
Warum sind unsere Bytes im Netzwerk nicht die gleichen wie in unserem Bild? Tatsache ist, dass Wireshark uns das Endergebnis zeigt, wie er alles entschlüsselt hat. Und im Netzwerk werden diese Bytes, diese Header, mit einem speziellen HPACK-Format komprimiert. Weitere Details finden Sie besser im Internet. Suchen Sie nach Informationen, es ist gut dokumentiert.
Kehren wir zu unseren Bissen zurück. Es gibt eine spezielle Feldinhaltskennung. Es gibt an, mit welcher Ressource diese Frames gerade arbeiten. In diesem Fall haben wir den ersten Frame gesendet und Daten empfangen. Wenn der Server uns die Inhaltsbytes selbst gibt, wird der Datenrahmen bereits verwendet.
Unsere Protokolle HTTP / 1 und HTTP / 2 sind sehr unterschiedlich. Wir haben bereits darüber gesprochen, dass HTTP / 1 ein Textprotokoll und HTTP / 2 ein Binärprotokoll ist, dh es funktioniert mit Frames.
HTTP / 1 gibt im Fall einer Anfrage in Form einer einzelnen Verbindung ein unbekanntes Ergebnis zurück, abhängig von der Implementierung, wie die Entwickler des Webservers es geschrieben haben. Das heißt, wenn wir zwei Anfragen in einer Verbindung stellen, wird höchstwahrscheinlich entweder eine Antwort auf die erste oder auf die zweite Anfrage zurückgegeben. Um Ressourcen parallel zu laden, stellt der Browser dazu mehrere Verbindungen her, normalerweise etwa sechs, und lädt Ressourcen parallel.
HTTP / 2 verwendet wiederum eine einzelne Verbindung. Das heißt, es stellt die Verbindung her und lädt alle erforderlichen Daten über Frames. Diese Technik zum Packen mehrerer Ressourcen in eine Verbindung wird als Multiplexing bezeichnet.
Aus der Funktionsweise unserer Verbindungen geht hervor, dass bei einem Paketverlust in einer der Verbindungen HTTP / 1 besser funktioniert. Höchstwahrscheinlich werden wir andere Verbindungen nicht berühren, sie werden weiterhin mit der gleichen Geschwindigkeit geladen. Und im Fall von HTTP / 2 verlangsamt sich das Laden aller Ressourcen, wenn unser Paket verloren geht.
Es scheint, dass HTTP / 2 schlechter ist, es ist auch empfindlich gegenüber Paketverlust. Wenn wir jede dieser sechs Verbindungen erstellen, führen wir die folgende Operation aus.
Der Client und der Server stellen eine zuverlässige Verbindung her, eine TCP-Verbindung. Wir senden zwei Pakete vom Client an den Server, und ein Paket wird von der Serverseite an den Client gesendet. Wir scheinen also zu sagen, dass wir bereit sind, Daten zu übertragen. Dies schafft natürlich Overhead-Ressourcen, wir können dies für eine lange Zeit tun.
Es gibt auch Verschlüsselung. Wenn Sie jetzt in Ihren Browser schauen, sehen Sie höchstwahrscheinlich ein Vorhängeschlosssymbol. Viele Leute nennen es SSL, aber es ist nicht wirklich SSL. Das ist TLS. SSL ist seit langem veraltet, wird praktisch nicht mehr unterstützt und sollte aufgegeben werden.
TLS hat auch Paketaustausch. Das heißt, wir legen wie bei einem TCP-Handshake einen bestimmten Status fest, nach dem wir weiterarbeiten können. Zu diesem Zeitpunkt können wir auch Optimierungen vornehmen, aber Browser unterstützen die Dinge, die wir bereits von der Serverseite aus aktiviert haben, noch nicht. Wir warten darauf, dass alle es einschalten.
Es war einmal, als HTTP / 1 versuchte, das Problem des gleichzeitigen Ladens von Ressourcen zu lösen. Der RFC hat es. Und es war einmal Pipelining implementiert. Aufgrund der Komplexität der Implementierung wird dies von Internet Explorer nicht unterstützt, während Firefox und Chrome dies tun. Die Unterstützung wurde jedoch im Laufe der Zeit eingestellt.
Jede unserer sechs Verbindungen, die wir bereits hergestellt haben, wird tatsächlich nicht geschlossen. Das heißt, sie werden weiterhin auf die gleiche Weise wie zuvor arbeiten. Hierzu wird eine Technik wie Keep-Alive verwendet. Das heißt, wir stellen eine zuverlässige Verbindung zu einem bestimmten Server her und arbeiten weiter.
Auf HTTP-Ebene wird dies vom Header gesteuert. In diesem Fall handelt es sich um eine Verbindung. Und auf TCP-Ebene werden wir bereits das Betriebssystem selbst verwenden, es wird für uns entscheiden, was zu tun ist.
Es gibt auch andere Probleme mit HTTP / 2. In HTTP / 2 können wir Pakete priorisieren und benötigte Daten schneller senden. In diesem Fall kann der Puffer auf dem Server überlaufen, wenn wir versuchen, viele Daten gleichzeitig zu senden. Dann werden die Pakete mit höherer Priorität einfach langsamer und gehen zum Ende der Warteschlange.
Paketverlust wird beobachtet. Sie verlangsamen unser Laden, und diese Blockierung wird als Head-of-Line-Blockierung bezeichnet.
Wie TCP Paketverlustprobleme löst
Jetzt werden wir über TCP sprechen, das heißt unsere vierte Schicht. In den nächsten zehn Minuten werde ich erläutern, wie TCP funktioniert.
Bei unserem Besuch bitten wir jemanden, das Salz zu geben. Wenn eine Person uns Salz gibt, bestätigen wir, dass das Salz uns erreicht hat. In diesem Fall nehmen wir auch ein Segment, senden es und warten auf Bestätigung. Wir senden wieder. Und wenn es einen Verlust gibt, leiten wir dieses Segment weiter und als Ergebnis wird es an uns geliefert. Diese Technik zum Senden eines Segments wird als Stop and Wait bezeichnet.
Aber unsere Netzwerke haben sich in den letzten 30 Jahren enorm beschleunigt. Vielleicht erinnern sich einige von Ihnen an die Einwahl, das Internet in Megabyte. Möglicherweise können Sie bereits zu Hause eine Verbindung zum Gigabit-Internet herstellen.
In diesem Fall können wir auch mehrere Pakete gleichzeitig senden. In unserem Beispiel gibt es drei davon. Wir senden das Fenster in Form von drei Paketen und warten, bis alle bestätigt sind.
Im Falle eines Paketverlusts können wir ab unserem ersten Verlust alle Pakete erneut weiterleiten. Diese Technik heißt Go-Back N. Andernfalls können wir alle Pakete verfolgen und nur die verlorenen weiterleiten. Diese Technik wird als selektive Wiederholung bezeichnet. Auf der Serverseite ist es teurer. Als wir die Folien vorbereiteten, dauerte es lange, bis wir herausgefunden hatten, wie wir sie präsentieren sollten. Ich selbst war verwirrt und habe mir deshalb eine solche Analogie ausgedacht.
Uns allen sind Rohre bekannt, durch die Wasser fließt. Die Rohre haben unterschiedliche Durchmesser, irgendwo können sie dünner sein, und in diesem Fall ist die engste Stelle nur bei unserem maximalen Durchsatz. Wir werden nicht mehr Wasser einschenken können, als dieser Engpass zulässt.
Wir werden versuchen, Bälle von links nach rechts zu schießen. Auf der rechten Seite werden wir bestätigt, dass die Bälle geflogen sind. Wir fangen an, einen Strom von Bällen zu senden. Werfen wir einen Blick auf den Schnitt. Jetzt fliegen die Bälle in eine Richtung, sie sind bestätigt und die Anzahl unserer Bälle wächst exponentiell. Irgendwann wird das Volumen der Kugeln so groß, dass sie langsamer werden und Verluste beginnen. Nach dem Verlust verlangsamen wir etwas, reduzieren unser Fenster um die Hälfte. Dann versuchen wir zu verstehen, was mit uns passiert ist. Die erste Stufe heißt TCP Slow Start.
Wenn wir das Fenster zweimal geschlossen haben, können wir die Verbindung wiederherstellen und die Jungs bitten, uns unsere Bälle erneut zu schicken. Sie rufen uns zu, dass wir die Bälle schicken müssen, wir antworten ihnen - hier sind deine Bälle. Diese Phase wird als schnelle Wiederherstellung und schnelle erneute Übertragung bezeichnet.
Als wir feststellten, dass bei uns alles in Ordnung ist, erhöhen wir allmählich die Anzahl der gesendeten Bälle, beginnend mit diesem zusammengeklappten Fenster. Diese Phase wird als Stauvermeidung bezeichnet. Das heißt, wir versuchen zu vermeiden, dass unsere Pakete verloren gehen.
Die Phase, in der unser Fenster zweimal zusammenfällt, wird als multiplikative Abnahme bezeichnet. Und die langsame Phase der Erhöhung der Anzahl der Kugeln wird als additive Erhöhung bezeichnet.
Wenn unsere Überlastungsvermeidung wieder Pakete verliert, können wir den nächsten Schritt tun. Im Moment interessieren wir uns jedoch mehr für das Bild dieses Diagramms. Wir sehen eine solche Säge, und diese Säge wird uns mehrmals nützlich sein. Denken Sie daran, wie es aussieht.
Wir werden auf die Probleme herkömmlicher TCP-Protokolle zurückkommen. In Analogie zu einer Pfeife gießen wir Säcke ein. Da es neben uns noch andere Benutzer im Internet gibt, beginnen sie auch, Pakete in die Pipe zu schütten. Irgendwann können die Puffer unserer Router überlaufen und Probleme beim Senden von Paketen verursachen.
Es gibt auch ein Problem mit dem Paketverlust in drahtlosen Netzwerken. Höchstwahrscheinlich verfügt Ihr Laptop nicht über einen Ethernet-Anschluss und Sie sehen ein Gespräch über WLAN. Der Paketverlust in Wi-Fi und Mobilfunknetzen wird nicht durch den Router selbst verursacht, sondern durch Funkstörungen. Diese Metrik wird für uns nicht sehr nützlich sein.
Unterschied von TCP BBR zu anderen Algorithmen
Hier kommen wir zu BBR. Es steht für Bottleneck Bandwidth und Round Trip Time. Dies sind Metriken für die Bandbreite, wenn wir unseren Kanal nicht vollständig verstopfen, und die Laufzeit des Pakets von uns zum Server und zurück.
Wenn wir Daten senden, wird der ideale Zustand, in dem sich Pakete in einem stabilen Zustand befinden, fliegen und noch nicht bestätigt wurden, als Bandbreitenverzögerungsprodukt bezeichnet. Wir können den BDP erhöhen, indem wir Puffer von Netzwerkgeräten verwenden. Wenn dieser Puffer überschritten wird, beginnen Verluste.
Und gewöhnliche TCP-Algorithmen arbeiten nur auf der rechten Seite des Diagramms, dh dort, wo Verluste auftreten - wir schütten so viele Pakete, dass Verluste unvermeidlich sind. Die Pakete werden langsamer und wir fangen an, das Fenster zu schließen.
BBR wiederum arbeitet nach einem anderen Prinzip in der Nähe unserer Pfeife. Wir schütten einfach so viele Taschen ein, wie wir überspringen können. In der Startphase, also ganz am Anfang, gießen wir die Beutel ein, bis die Überlastung beginnt.
Und manchmal ist Paketverlust möglich. Aber BBR versucht, diesen Moment zu vermeiden. Wenn wir unsere Pfeife gefüllt haben, rollen wir zurück. Diese Phase wird Drain genannt.
Wir kehren zu unserer stabilen Verbindung zurück, wo sie vollständig gefüllt wird, aber gleichzeitig werden wir keine zusätzlichen Puffer, keine zusätzlichen Reservoire verwenden. Von dieser Position aus arbeitet BBR weiter.
Von Zeit zu Zeit werden wir uns ansehen, was mit unserem Netzwerk passiert. Wir verfolgen fast jedes Paket, das an uns zurückgesandt wird. Wenn die Pakete an uns zurückgesandt werden, versuchen wir, die Anzahl der Pakete leicht zu beschleunigen und die Pakete selbst zu beschleunigen, indem wir sie an das Netzwerk senden.
Und wenn wir keine Probleme haben, können wir bei diesem Wert bleiben. Das heißt, weiterhin in dem Tempo zu arbeiten, das für uns angenehm ist. Wenn es jedoch Verluste gab, können wir einen Rollback durchführen.
Als wir die Bestätigung erhielten, dass sich die Geschwindigkeit verbessert hat, können wir ein wenig warten und das Intervall von zehn Sekunden betrachten. Und wenn wir während dieses Intervalls feststellen, dass die Geschwindigkeit des Sendens von Paketen zunimmt und Pakete schneller bestätigt werden, können wir in die RTT-Phase der Sonde eintreten und prüfen, ob alles besser geworden ist.
Solche Phasen wechseln sich ab, das heißt, wir werden ständig überprüfen, was wir mit dem Netzwerk haben.
Der BBR-Algorithmus basiert nicht mehr auf Paketverlust, sondern auf der Kanalbreite und der Paketlaufzeit.
Tatsächlich ist es immun gegen Paketverlust. Er reagiert praktisch nicht auf sie, und deshalb haben wir einige Probleme. Google hat versprochen, dass diese Probleme in BBR v2 behoben werden.
Wir haben unsere Phasen untersucht, und vor uns liegt wieder der Kamm, den ich bereits gezeigt habe. Normale TCP-Protokolle werden rot hervorgehoben. Also nimmt er auf, nimmt auf, verlangsamt sich und verliert wieder Pakete. Und BBR legt das Tempo fest, mit dem er die ganze Zeit arbeiten wird, und überprüft ständig unser Netzwerk, um festzustellen, ob es etwas besser geworden ist. Und es kann sich beschleunigen.
Unsere Metriken werden ständig aktualisiert. Wir verfolgen jede Bestätigung des Kunden und prüfen, ob sich unser Netzwerk beschleunigt hat oder nicht.
Wie wird diese Rate des Sendens von Paketen gesteuert? Wir steuern das Sendetempo mithilfe der Stimulationstechnik. Es ist in dem zuvor erwähnten Scheduler implementiert. Dies ist der FQ-Scheduler. Es ist auch im Kernel selbst implementiert, aber ich werde später darüber sprechen.
Wir versuchen, wie in einer Pipe, mehr Daten zu gießen und gleichzeitig nicht zu verlangsamen, unsere Pakete nicht zu verlieren. Aber BBR ist nicht so einfach. Höchstwahrscheinlich leben Sie in Containern oder verwenden mehrere Server für Datenbanken - möglicherweise für Bilder.
Und alle diese Server interagieren miteinander. Es ist normales TCP aktiviert, nicht BBR. Und wenn Sie die Säge haben, die wir bereits gesehen haben, wenn das Fenster zu kollabieren beginnt, dann beginnt BBR möglicherweise zu tappen, dass das Fenster kollabiert, und erhöht die Rate des Sendens von Paketen. Somit wird es gewöhnliches TCP aus unserem Netzwerk verdrängen, dominieren.
Wenn das Netzwerk sehr schlecht ist, sind andere Probleme möglich. Normales TCP funktioniert überhaupt nicht, und da BBR praktisch unempfindlich gegenüber Paketverlusten ist, funktioniert es mit einer bestimmten Rate weiter.
Wir können dieses Problem mit Rechenzentren mit der Option TCP_CONGESTION lösen. Es ist für jede Steckdose, für jede Verbindung verfügbar. Soweit ich weiß, ist diese Option auf fast keinem Webserver implementiert. Und unser L7 Balancer unterstützt dies. Aber zurück zu unserem Tempo. Wenn Sie mit älteren Kerneln arbeiten, gab es vor Version 4.20 einen Fehler in der Stimulationsimplementierung in Kerneln. In diesem Fall lohnt es sich, den FQ-Scheduler zu verwenden.
Nachdem Sie nun wissen, wie TCP funktioniert, können Sie sich an Ihren Systemadministrator wenden und ihm mitteilen, warum Sie BBR aktivieren sollten.
Kehren wir zu unseren zehn Prozent zurück. Woher können sie kommen? Betreibernetzwerke sind jetzt sehr groß. Es geht alles um's Geld. Sie können beispielsweise Kanäle für 100, 200 Terabit erstellen und eine große Anzahl von 4K-Videos überspringen. Ihr Client befindet sich jedoch weiterhin am Endpunkt.
Und höchstwahrscheinlich wird diese letzte Meile zum Kunden die Quelle von Problemen sein. Alle unsere Wi-Fi und LTE verlieren Pakete. Bei Verwendung von regulärem TCP werden Verlangsamungen auftreten. BBR löst dieses Problem. Sie können es mit nur den beiden von mir angegebenen Befehlen einschalten. Danke an alle.