Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 6958|Răspunde: 1

Multithreading-ul pune scalabilitatea într-un impas

[Copiază linkul]
Postat pe 06.12.2014 22:21:58 | | |
Acesta este un articol din lumea Python, dar este totuși aplicabil întregului domeniu al programării, deși multithreading-ul ne permite procesarea cererilor mai rapid, dar există și un plafon, firele verzi (micro-thread) fiind soluția.

Dezvoltarea software multithreaded rezolvă un număr mare de probleme, în special pentru aplicațiile centrate pe rețea care necesită performanțe solicitante pentru a răspunde rapid utilizatorilor. Din păcate, multithreading-ul nu este suficient pentru a rezolva la scară largăConcurențăprobleme sexuale.

Abordarea acestor probleme necesită schimbarea modelelor de programare, folosind evenimente asincrone și mecanisme bazate pe callback. La Druva, am creat o bibliotecă python numită Dhaga pentru a rezolva cazuri la scară largăConcurență, în timp ce modelul de programare nu necesită modificări semnificative.

Dezvoltatorii de software trăiesc într-unaConcurențălumea. Thread-urile sunt cetățeni de primă clasă astăzi, mai ales în timpul dezvoltării, mai ales când aplicația ta realizează operațiuni intensive de rețea, precum sistemul inSync (produs de sincronizare a securității rețelei) precum Druva. Multithreading-ul ajută la simplificarea și ordinea fluxului codului de programare pentru operațiunile de rețea. Când aplicația noastră are nevoie de îmbunătățiri sau îmbunătățiri de performanță, poate fi îmbunătățităElasticitate, putem crește numărul de fire.

Dar când vine vorba de mii de cântaruriConcurențăcererile, firele de discuție nu sunt suficiente.

Am constatat că multithreading-ul are următoarele dezavantaje:
1. Clientul de sistem inSync trebuie să facă backup la un număr mare de fișiere către server prin apeluri RPC de rețea. O metodă tipică pentru dezvoltatori de a accelera lucrurile este să folosească firele de discuție. Totuși, performanța adusă de multi-threading crește costul memoriei și al procesorului; Dezvoltatorii trebuie să mențină un echilibru între viteză și numărul de fire.

2. Serverele noastre trebuie să gestioneze între sistemul inSync și mii de cliențiConcurențăConexiuni și notificări. Pentru a gestiona eficient conexiunile, folosim fire de discuție pentru a gestiona cererile. Dar numărul tot mai mare de clienți ai sistemului inSync înseamnă, de asemenea, că trebuie să continuăm să creștem numărul de fire, ceea ce consumă multă memorie de server și CPU.

3. Serverul nostru web trebuie să gestioneze mii de cereri HTTP paralele. Majoritatea muncii este pe socket-urile de rețea care primesc și trimit date și le transmit către backend-ul sistemului inSync. Face ca majoritatea firelor să aștepte operațiunile de rețea. Cauzând problema C10K, atunci când există mii de cereri sincrone către serverul web, generarea unui fir de discuție pentru fiecare cerere este destul de nescalabilă (Scalare).

Limitările cadrelor asincrone
Multe framework-uri asincrone, inclusiv Twisted, Tornado Tornado și asyncore, pot ajuta dezvoltatorii să renunțe la metodele populare de utilizare a thread-urilor. Aceste cadre se bazează pe socket-uri neblocante și mecanisme de callback (similare cu Node.js). Dacă folosim aceste framework-uri așa cum sunt, părțile principale ale codului nostru Druva vor trebui refactorizate. Nu asta vrem să facem. Refactorizarea codului crește ciclurile de dezvoltare și testare, împiedicându-ne să ne îndeplinim cerințele de scară. Având în vedere că mai multe părți ale produsului trebuie să fie masive, fiecare dintre noi va trebui să le refactorizeze – de aici și efortul de a dubla sau tripla.

Pentru a evita schimbarea prea multor coduri, a trebuit să renunțăm la utilizarea directă a cadrului existent. Din fericire, am găsit câteva unelte utile.

Pentru că vrem să controlăm execuția codului pe I/O de rețea, avem nevoie de o modalitate de a împărți un fir în micro-fire. GăsimGreenlets。 Oferă o programare microthread neimplicită numită co-rutină. Cu alte cuvinte. Este util când vrei să-ți controlezi codul care rulează. Poți construi microthread-uri pentru programe personalizate pentru că poți controla când greenlet-urile apar pauze. Acest lucru este perfect pentru noi pentru că ne oferă control total asupra programării codului nostru.

Tornado este un framework simplu, fără blocare, pentru servere web, scris în Python, conceput să gestioneze mii de cereri asincrone. Folosim componenta sa de bază, IOLoop IOStream. IOLoop este o buclă de evenimente I/O cu socket neblocant; Folosește epoll (pe Linux) sau cozi (BSD și Mac OS X), altfel selectați (pe Windows) dacă sunt disponibile. IOStream oferă socluri neblocante, cum ar fi ambalare convenabilă pentru citire și scriere. Delegăm toate operațiunile de socket către Tornado și apoi folosim callback-uri pentru a declanșa operațiunile de cod pentru finalizare (notă banq: foarte similar cu mecanismul Node.js).

Este un început bun, dar avem nevoie de mai mult. Dacă folosim modulul de mai sus direct în codul nostru, o mare parte din codul nostru RPC va trebui să se schimbe, programând RPC prin greenlets, asigurându-ne că greenlet-urile nu blochează (dacă greenlet-urile se blochează, se va bloca întregul fir de discuție și toate celelalte), gestionând funcțiile de callback din tornado.

Avem nevoie de o abstracție pentru a gestiona și aranja greenlet-urile pentru a evita blocarea lor cu apeluri externe, iar această abstracție poate fi masiv scalabilă dincolo de firele de execuție. Această abstracție este Dhaga, care permite programarea fluxului de cod al aplicației ca o secvență sincronă tradițională, dar execuția este asincronă.

Dhaga (din hindi, care înseamnă thread) este un cadru de execuție pentru un fir ușor pe care îl abstractizăm. Clasa Dhaga derivă din greenlets și folosește comutarea stack-ului pentru a executa mai multe fluxuri de cod într-un singur fir de execuție al sistemului de operare. Firele unui sistem de operare execută mai multe dhagas folosind programare colaborativă. Ori de câte ori un dhaga așteaptă (în principal așteptând un apel RPC să revină), el cedează controlul către nivelul părinte (adică contextul de execuție al firului de operare care l-a creat). Nivelul părinte programează apoi un alt dhaga pentru a fi gata de rulat. Apelul RPC va fi transmis serverului web tornado pentru a scrie Socket-ul asincron, apoi va înregistra un callback când revine, iar când acest RPC revine, dhaga aflat în așteptare va fi adăugat la coada executabilului și apoi preluat de firul părinte. (Notă Banq: similar cu principiul node.js)

Putem folosi Dhaga în loc de fire pentru operațiuni cu latență mare și folosim 512 dhagas într-un singur fir atunci când numărul de fire crește dincolo de limita rezonabilă de debit.







Precedent:Modelul cadrului MVC este mort
Următor:Avantaje și dezavantaje ale cadrelor MVC:
Postat pe 07.12.2014 17:22:55 |
Cititul și postarea înapoi este o virtute
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com