Dieser Artikel ist ein Spiegelartikel der maschinellen Übersetzung, bitte klicken Sie hier, um zum Originalartikel zu springen.

Ansehen: 6958|Antwort: 1

Multithreading bringt die Skalierbarkeit in eine Sackgasse

[Link kopieren]
Veröffentlicht am 06.12.2014 22:21:58 | | |
Dies ist ein Artikel aus der Python-Welt, aber er ist weiterhin auf das gesamte Programmierfeld anwendbar, obwohl Multithreading uns erlaubt, Anfragen schneller zu verarbeiten, aber es gibt auch eine Obergrenze, grüne (Micro-Thread) Threads sind die Lösung.

Die Entwicklung von Multithreaded-Software löst eine Vielzahl von Problemen, insbesondere für netzwerkzentrierte Anwendungen, die anspruchsvolle Leistung erfordern, um schnell auf Nutzer zu reagieren. Leider reicht Multithreading nicht aus, um großflächige Fälle zu lösenNebenführungsexuelle Probleme.

Um diese Probleme zu lösen, müssen Programmiermodelle geändert werden, indem asynchrone Ereignisse und rückrufbasierte Mechanismen verwendet werden. Bei Druva haben wir eine Python-basierte Bibliothek namens Dhaga entwickelt, um großflächige Lösungen zu lösenNebenführung, während das Programmiermodell keine wesentlichen Änderungen erfordert.

Softwareentwickler leben in einemNebenführungWelt. Threads sind heute erstklassige Bürger, besonders während der Entwicklung, besonders wenn Ihre Anwendung intensive Netzwerkoperationen ausführt, wie das inSync-System (Netzwerksicherheitssynchronisationsprodukt) wie Druva. Multithreading erleichtert den Fluss des Programmiercodes für Netzwerkoperationen einfach und geordnet. Wenn unsere Anwendung Leistungsverbesserungen oder -verbesserungen benötigt, kann sie verbessert werdenElastizität, wir können die Anzahl der Threads erhöhen.

Aber wenn es um Tausende von Skalen geht,NebenführungAnfragen, Threads reichen nicht aus.

Wir stellten fest, dass Multithreading folgende Nachteile hat:
1. Der inSync-Systemclient muss eine große Anzahl von Dateien über Netzwerk-RPC-Aufrufe auf den Server sichern. Eine typische Möglichkeit für Entwickler, Dinge zu beschleunigen, ist die Verwendung von Threads. Die durch Multithreading erzielte Leistung erhöht jedoch die Kosten für Speicher und CPU; Entwickler müssen ein Gleichgewicht zwischen Geschwindigkeit und Threadzahl halten.

2. Unsere Server müssen zwischen dem inSync-System und Tausenden von Kunden abwechselnNebenführungVerbindungen und Benachrichtigungen. Um Verbindungen effizient zu handhaben, verwenden wir Threads zur Bearbeitung von Anfragen. Aber die wachsende Zahl von inSync-Systemkunden bedeutet auch, dass wir die Anzahl der Threads weiter erhöhen müssen, was viel Serverspeicher und CPU beansprucht.

3. Unser Webserver muss Tausende paralleler HTTP-Anfragen verarbeiten. Der Großteil der Arbeit liegt an den Netzwerksockets, die Daten empfangen und senden und an das Backend des inSync-Systems weiterleiten. Das führt dazu, dass die meisten Threads auf Netzwerkoperationen warten. Das C10K-Problem verursacht wird: Wenn es tausende synchrone Anfragen an den Webserver gibt, ist das Erstellen eines Threads für jede Anfrage ziemlich nicht skalierbar (Scale).

Einschränkungen asynchroner Frameworks
Viele asynkrone Frameworks, darunter Twisted, Tornado Tornado und asyncore, können Entwicklern helfen, sich von den gängigen Nutzungsmethoden von Threads zu entfernen. Diese Frameworks basieren auf blockfreien Sockets und Callback-Mechanismen (ähnlich wie Node.js). Wenn wir diese Frameworks so verwenden, wie sie sind, müssen die Hauptteile unseres Druva-Codes umstrukturiert werden. Das ist nicht das, was wir tun wollen. Das Refactoring von Code erhöht Entwicklungs- und Testzyklen und verhindert, dass wir unsere Skalierungsanforderungen erfüllen. Da mehrere Teile des Produkts massiv sein müssen, muss jeder von uns sie refaktorisieren – daher der Aufwand, zu verdoppeln oder zu verdreifachen.

Um nicht so viel Code zu ändern, mussten wir uns von der direkten Nutzung des bestehenden Frameworks entfernen. Zum Glück haben wir einige nützliche Werkzeuge gefunden.

Da wir die Ausführung von Code auf der Netzwerk-I/O steuern wollen, brauchen wir eine Möglichkeit, einen Thread in Mikro-Threads zu unterteilen. Wir findenGrünlinge。 Sie bietet eine nicht-implizite Mikrothread-Planung, die als Co-Routine-Coroutine bezeichnet wird. Mit anderen Worten,. Es ist nützlich, wenn du den laufenden Code steuern willst. Du kannst Mikrothreads für benutzerdefinierte Zeitpläne erstellen, weil du kontrollieren kannst, wann Greenlets Pausen ergeben. Das ist perfekt für uns, weil es uns die volle Kontrolle über die Planung unseres Codes gibt.

Tornado ist ein einfaches, blockfreies Webserver-Framework, das in Python geschrieben ist und für Tausende asynchroner Anfragen entwickelt wurde. Wir verwenden seine Kernkomponente, IOLoop IOStream. IOLoop ist eine nicht-blockierende Socket-I/O-Ereignisschleife; Es verwendet epoll (unter Linux) oder Warteschlangen (BSD und Mac OS X), ansonsten wählen Sie (unter Windows), falls diese verfügbar sind. IOStream bietet blockierungsfreie Sockets wie praktische Verpackungen zum Lesen und Schreiben. Wir delegieren alle Socket-Operationen an Tornado und nutzen dann Callbacks, um Code-Operationen auszulösen (banq-Hinweis: sehr ähnlich zu Node.js Mechanismus).

Es ist ein guter Anfang, aber wir brauchen mehr. Wenn wir das oben genannte Modul direkt in unserem Code verwenden, muss sich ein Großteil unseres RPC-Codes ändern, RPC über Greenlets planen, sicherstellen, dass Greenlets nicht blockieren (wenn Greenlets verstopft werden, verstopft das den gesamten Thread und alle anderen), und Callback-Funktionen aus Tornado übernehmen.

Wir brauchen eine Abstraktion, um Greenlets zu verwalten und zu ordnen, damit sie nicht mit externen Aufrufen verstopft werden, und diese Abstraktion kann über Threads hinaus massiv skalierbar sein. Diese Abstraktion ist Dhaga, was es ermöglicht, den Anwendungscodefluss wie eine traditionelle synchrone Sequenz zu programmieren, wobei die Ausführung asynchron erfolgt.

Dhaga (aus dem Hindi, was Thread bedeutet) ist ein Ausführungsrahmen für einen leichtgewichtigen Thread, den wir abstrahieren. Die Dhaga-Klasse leitet sich von Greenlets ab und verwendet Stack-Switching, um mehrere Codeflows in einem einzigen Betriebssystem-Thread auszuführen. Threads eines Betriebssystems führen mehrere Dhagasen mittels kollaborativer Planung aus. Wann immer ein Dhaga wartet (hauptsächlich auf die Rückkehr eines RPC-Aufrufs), übergibt er die Kontrolle an die Elternebene (d. h. den Ausführungskontext des OS-Threads, der ihn erstellt hat). Das Elternlevel plant dann ein weiteres Dhaga, das bereit zum Ausführen ist. Der RPC-Aufruf wird an den Tornado-Webserver weitergeleitet, um den Socket asynchron zu schreiben, und registriert dann einen Rückruf, wenn er zurückkehrt; wenn dieser RPC zurückkehrt, wird das wartende Dhaga der ausführbaren Warteschlange hinzugefügt und vom Elternthread übernommen. (Banq-Anmerkung: ähnlich node.js Prinzip)

Wir können Dhaga anstelle von Threads für Operationen mit hoher Latenz verwenden, und wir verwenden 512 Dhagas in einem einzelnen Thread, wenn die Anzahl der Threads über eine angemessene Durchsatzgrenze hinaus steigt.







Vorhergehend:Das MVC-Framework-Muster ist tot
Nächster:Vor- und Nachteile von MVC-Frameworks:
Veröffentlicht am 07.12.2014 17:22:55 |
Lesen und Zurückposten ist eine Tugend
Verzichtserklärung:
Alle von Code Farmer Network veröffentlichten Software, Programmiermaterialien oder Artikel dienen ausschließlich Lern- und Forschungszwecken; Die oben genannten Inhalte dürfen nicht für kommerzielle oder illegale Zwecke verwendet werden, andernfalls tragen die Nutzer alle Konsequenzen. Die Informationen auf dieser Seite stammen aus dem Internet, und Urheberrechtsstreitigkeiten haben nichts mit dieser Seite zu tun. Sie müssen die oben genannten Inhalte innerhalb von 24 Stunden nach dem Download vollständig von Ihrem Computer löschen. Wenn Ihnen das Programm gefällt, unterstützen Sie bitte echte Software, kaufen Sie die Registrierung und erhalten Sie bessere echte Dienstleistungen. Falls es eine Verletzung gibt, kontaktieren Sie uns bitte per E-Mail.

Mail To:help@itsvse.com