Linuxi võrgurakenduse jõudlus. Sissejuhatus

Veebirakendusi kasutatakse nüüd kõikjal ja kõigi transpordiprotokollide hulgas on HTTP-l lõviosa. Veebirakenduste arendamise nüansse uurides pöörab enamik inimesi väga vähe tähelepanu operatsioonisüsteemile, kus need rakendused tegelikult töötavad. Arenduse (Dev) ja operatsioonide (Ops) eraldamine muutis olukorra ainult hullemaks. Kuid DevOpsi kultuuri tõusuga hakkavad arendajad vastutama oma rakenduste pilves käitamise eest, seega on neil väga kasulik tutvuda operatsioonisüsteemi taustaga põhjalikult. See on eriti kasulik, kui proovite juurutada süsteemi tuhandete või kümnete tuhandete samaaegsete ühenduste jaoks.

Veebiteenuste piirangud on väga sarnased teiste rakenduste piirangutega. Olgu need koormuse tasakaalustajad või andmebaasiserverid, kõigil neil rakendustel on suure jõudlusega keskkonnas sarnased probleemid. Nende põhipiirangute mõistmine ja nende ületamine üldiselt aitab teil hinnata oma veebirakenduste jõudlust ja mastaapsust.

Kirjutan seda artiklite seeriat vastuseks noorte arendajate küsimustele, kes soovivad saada hästi informeeritud süsteemiarhitektideks. Linuxi rakenduste optimeerimise tehnikaid on võimatu selgelt mõista, sukeldumata nende operatsioonisüsteemi tasemel töötamise põhitõdedesse. Kuigi rakendusi on mitut tüüpi, tahan selles sarjas uurida veebipõhiseid rakendusi, mitte töölauarakendusi, nagu brauser või tekstiredaktor. See materjal on mõeldud arendajatele ja arhitektidele, kes soovivad mõista, kuidas Linuxi või Unixi programmid töötavad ja kuidas neid suure jõudlusega struktureerida.

Linux on serveriruum operatsioonisüsteemi ja enamasti töötavad teie rakendused selles OS-is. Kuigi ma ütlen "Linux", võite enamasti julgelt eeldada, et pean silmas kõiki Unixi-laadseid operatsioonisüsteeme üldiselt. Samas pole ma kaasasolevat koodi teistes süsteemides testinud. Seega, kui olete huvitatud FreeBSD-st või OpenBSD-st, võivad teie tulemused erineda. Kui ma proovin midagi Linuxi spetsiifilist, juhin seda tähelepanu.

Kuigi saate neid teadmisi kasutada rakenduse nullist ülesehitamiseks ja see on ideaalselt optimeeritud, on parem seda mitte teha. Kui kirjutate oma organisatsiooni ärirakenduse jaoks uue veebiserveri C või C++ keeles, võib see olla teie viimane tööpäev. Kuid nende rakenduste struktuuri tundmine aitab olemasolevaid programme valida. Saate võrrelda protsessipõhiseid süsteeme nii lõimepõhiste kui ka sündmustepõhiste süsteemidega. Saate aru ja hindate, miks Nginx töötab paremini kui Apache httpd, miks Tornado-põhine Pythoni rakendus suudab teenindada rohkem kasutajaid kui Django-põhine Pythoni rakendus.

ZeroHTTPd: õppetööriist

ZeroHTTPd on veebiserver, mille kirjutasin algusest peale C-s õppevahendina. Sellel pole väliseid sõltuvusi, sealhulgas juurdepääsu Redisele. Teeme oma Redise protseduure. Täpsemat teavet leiate altpoolt.

Kuigi võiksime teooriat pikalt arutada, pole midagi paremat kui koodi kirjutamine, selle käivitamine ja kõigi serveriarhitektuuride omavaheline võrdlemine. See on kõige ilmsem meetod. Seetõttu kirjutame iga mudeli abil lihtsa ZeroHTTPd veebiserveri: protsessipõhise, lõimepõhise ja sündmusepõhise. Vaatame kõiki neid servereid ja vaatame, kuidas need üksteisega võrreldes toimivad. ZeroHTTPd on realiseeritud ühes C-failis. Sündmuspõhine server sisaldab uthash, suurepärane räsitabeli rakendus, mis on saadaval ühes päisefailis. Muudel juhtudel pole sõltuvusi, et projekti mitte keerulisemaks muuta.

Koodis on palju kommentaare, mis aitavad teil mõista. Olles lihtne veebiserver mõne koodireaga, on ZeroHTTPd ka minimaalne veebiarenduse raamistik. Sellel on piiratud funktsionaalsus, kuid see on võimeline teenindama staatilisi faile ja väga lihtsaid "dünaamilisi" lehti. Pean ütlema, et ZeroHTTPd on hea suure jõudlusega Linuxi rakenduste loomise õppimiseks. Üldiselt ootab enamik veebiteenuseid päringuid, kontrollib neid ja töötleb neid. See on täpselt see, mida ZeroHTTPd teeb. See on õppimise, mitte tootmise tööriist. See ei ole suurepärane vigade käsitlemisel ja tõenäoliselt ei kiidelda parimate turvatavadega (jah, ma kasutasin strcpy) või C-keele nutikaid nippe. Aga ma loodan, et see teeb oma tööd hästi.

Linuxi võrgurakenduse jõudlus. Sissejuhatus
ZeroHTTPd koduleht. See võib väljastada erinevaid failitüüpe, sealhulgas pilte

Külalisteraamatu rakendus

Kaasaegsed veebirakendused ei piirdu tavaliselt staatiliste failidega. Neil on keeruline suhtlus erinevate andmebaaside, vahemäludega jne. Seega loome lihtsa veebirakenduse nimega "Külaliste raamat", kuhu külastajad jätavad sissekanded oma nimede alla. Külalisteraamat salvestab varem jäetud sissekanded. Lehe allservas on ka külastajate loendur.

Linuxi võrgurakenduse jõudlus. Sissejuhatus
Veebirakendus "Külaliste raamat" ZeroHTTPd

Külastajate loendur ja külalisteraamatu kirjed on salvestatud Redis. Redisega suhtlemiseks rakendatakse oma protseduure, need ei sõltu välisest teegist. Ma ei ole suur homebrew koodi levitamise fänn, kui on olemas avalikult kättesaadavad ja hästi testitud lahendused. Kuid ZeroHTTPd eesmärk on uurida Linuxi jõudlust ja juurdepääsu välistele teenustele, samas kui HTTP-päringute teenindamisel on jõudlusele tõsine mõju. Peame täielikult kontrollima suhtlust Redisega igas oma serveriarhitektuuris. Mõnes arhitektuuris kasutame kõnede blokeerimist, teistes sündmustepõhiseid protseduure. Välise Redise klienditeegi kasutamine seda juhtimist ei paku. Lisaks täidab meie väike Redise klient vaid mõnda funktsiooni (võtme hankimine, seadistamine ja suurendamine; massiivi hankimine ja lisamine). Lisaks on Redise protokoll äärmiselt elegantne ja lihtne. Te ei pea seda isegi spetsiaalselt õpetama. Juba fakt, et protokoll teeb kogu töö ära umbes saja koodireal, näitab, kui läbimõeldud see on.

Järgmine joonis näitab, mida rakendus teeb, kui klient (brauser) seda nõuab /guestbookURL.

Linuxi võrgurakenduse jõudlus. Sissejuhatus
Kuidas külalisteraamatu rakendus töötab

Kui külalisteraamatu leht on vaja väljastada, tuleb failisüsteemile üks kõne malli mällu lugemiseks ja kolm võrgukõnet Redisele. Mallifail sisaldab suuremat osa ülaloleval ekraanipildil oleva lehe HTML-i sisust. Sisu dünaamilise osa jaoks on olemas ka spetsiaalsed kohahoidjad: postitused ja külastajaloendur. Saame need Rediselt kätte, sisestame lehele ja pakume kliendile täielikult vormistatud sisu. Kolmandat kõnet Redisele saab vältida, kuna Redis tagastab suurendamisel uue võtme väärtuse. Meie serveri jaoks, millel on asünkroonne sündmustepõhine arhitektuur, on aga palju võrgukõnesid õppimise jaoks hea proovikivi. Seega jätame külastajate arvu Redise tagastusväärtuse kõrvale ja küsime seda eraldi kõnega.

Serveri arhitektuurid ZeroHTTPd

Ehitame seitse ZeroHTTPd versiooni, millel on samad funktsioonid, kuid erinevad arhitektuurid:

  • Iteratiivne
  • Fork server (üks alamprotsess päringu kohta)
  • Pre-fork server (protsesside eelhargimine)
  • Täitelõimedega server (üks lõim päringu kohta)
  • Teemeeelse loomisega server
  • Arhitektuuripõhine poll()
  • Arhitektuuripõhine epoll

Mõõdame iga arhitektuuri jõudlust, laadides serverisse HTTP-päringuid. Kuid kui võrrelda väga paralleelseid arhitektuure, siis päringute arv suureneb. Testime kolm korda ja arvutame keskmise.

Testimise metoodika

Linuxi võrgurakenduse jõudlus. Sissejuhatus
ZeroHTTPd koormustesti seadistamine

Testide tegemisel on oluline, et kõik komponendid ei töötaks samas masinas. Sel juhul tekitab OS täiendavat ajakava koostamist, kuna komponendid konkureerivad protsessori pärast. Iga valitud serveriarhitektuuri operatsioonisüsteemi üldkulude mõõtmine on selle harjutuse üks olulisemaid eesmärke. Rohkemate muutujate lisamine muutub protsessile kahjulikuks. Seetõttu toimib kõige paremini ülaltoodud pildi seadistus.

Mida kõik need serverid teevad?

  • load.unixism.net: see on koht, kus me jookseme ab, Apache Benchmarki utiliit. See genereerib meie serveriarhitektuuride testimiseks vajaliku koormuse.
  • nginx.unixism.net: mõnikord tahame käitada rohkem kui ühte serveriprogrammi eksemplari. Selleks töötab Nginxi server koos vastavate seadistustega koormuse tasakaalustajana, mis tuleb ab meie serveriprotsessidele.
  • zerohttpd.unixism.net: siin käitame oma serveriprogramme korraga seitsmel erineval arhitektuuril.
  • redis.unixism.net: see server käivitab Redise deemoni, kuhu salvestatakse külalisteraamatu kirjed ja külastajaloendurid.

Kõik serverid töötavad samal protsessori tuumal. Idee on hinnata iga arhitektuuri maksimaalset jõudlust. Kuna kõiki serveriprogramme testitakse sama riistvaraga, on see võrdlusalus. Minu testseade koosneb Digital Oceanilt renditud virtuaalserveritest.

Mida me mõõdame?

Saate mõõta erinevaid näitajaid. Hindame iga arhitektuuri jõudlust antud konfiguratsioonis, laadides serveritele erineva paralleelsuse tasemega päringuid: koormus kasvab 20-lt 15 000 samaaegse kasutajani.

Katsetulemused

Järgmine diagramm näitab serverite jõudlust erinevatel arhitektuuridel erinevatel paralleelsuse tasemetel. Y-teljel on taotluste arv sekundis, x-teljel on paralleelühendused.

Linuxi võrgurakenduse jõudlus. Sissejuhatus

Linuxi võrgurakenduse jõudlus. Sissejuhatus

Linuxi võrgurakenduse jõudlus. Sissejuhatus

Allpool on tabel tulemustega.

taotlusi sekundis

paralleelsus
iteratiivne
kahvel
eelhark
voogesitus
eelstriimimine
küsitlus
epoll

20
7
112
2100
1800
2250
1900
2050

50
7
190
2200
1700
2200
2000
2000

100
7
245
2200
1700
2200
2150
2100

200
7
330
2300
1750
2300
2200
2100

300
-
380
2200
1800
2400
2250
2150

400
-
410
2200
1750
2600
2000
2000

500
-
440
2300
1850
2700
1900
2212

600
-
460
2400
1800
2500
1700
2519

700
-
460
2400
1600
2490
1550
2607

800
-
460
2400
1600
2540
1400
2553

900
-
460
2300
1600
2472
1200
2567

1000
-
475
2300
1700
2485
1150
2439

1500
-
490
2400
1550
2620
900
2479

2000
-
350
2400
1400
2396
550
2200

2500
-
280
2100
1300
2453
490
2262

3000
-
280
1900
1250
2502
suur levik
2138

5000
-
suur levik
1600
1100
2519
-
2235

8000
-
-
1200
suur levik
2451
-
2100

10
-
-
suur levik
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Graafikult ja tabelist on näha, et üle 8000 samaaegse päringu on meil alles vaid kaks mängijat: pre-fork ja epoll. Koormuse kasvades töötab küsitlusel põhinev server halvemini kui voogesituse server. Lõime-eelne arhitektuur on epolli vääriline konkurent, mis annab tunnistust sellest, kui hästi Linuxi kernel ajastab palju lõime.

ZeroHTTPd lähtekood

ZeroHTTPd lähtekood siin. Iga arhitektuuri jaoks on eraldi kataloog.

ZeroHTTPd │ ├── 01_iteratiivne │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking ─..c ├── 04_preforking ─. 05_ keermestamine │ ├── main.c ├── 06_eellõigutamine │ ├── main.c ├── 07_poll │ ├── main.c ├── XNUMX_epoll │ └─── Avalik fail.c ─│├── ├── register .html │ └── tux png └── mallid └── külalisteraamat └── index.html

Lisaks seitsmele kataloogile kõigi arhitektuuride jaoks on tippkataloogis veel kaks: avalik ja mallid. Esimene sisaldab faili index.html ja pilti esimesest ekraanipildist. Saate sinna panna muid faile ja kaustu ning ZeroHTTPd peaks neid staatilisi faile ilma probleemideta teenindama. Kui brauseris olev tee ühtib avaliku kausta teega, otsib ZeroHTTPd sellest kataloogist faili index.html. Külalisteraamatu sisu genereeritakse dünaamiliselt. Sellel on ainult avaleht ja selle sisu põhineb failil 'templates/guestbook/index.html'. ZeroHTTPd lisab lihtsalt laienduseks dünaamilisi lehti. Idee seisneb selles, et kasutajad saavad sellesse kataloogi malle lisada ja vajadusel ZeroHTTPd laiendada.

Kõigi seitsme serveri koostamiseks käivitage make all tipptaseme kataloogist – ja kõik järgud kuvatakse selles kataloogis. Käivitavad failid otsivad avalikke ja mallikatalooge kataloogist, kust need käivitatakse.

Linuxi API

Selles artikliseerias sisalduva teabe mõistmiseks ei pea te Linuxi API-ga hästi kursis olema. Siiski soovitan sellel teemal rohkem lugeda, Internetis on palju viiteallikaid. Kuigi käsitleme mitut Linuxi API-de kategooriat, keskendume peamiselt protsessidele, lõimedele, sündmustele ja võrgupinule. Lisaks Linuxi API-t käsitlevatele raamatutele ja artiklitele soovitan lugeda ka mana süsteemikutsete ja kasutatavate teegifunktsioonide jaoks.

Jõudlus ja mastaapsus

Üks märkus jõudluse ja mastaapsuse kohta. Teoreetiliselt pole nende vahel mingit seost. Teil võib olla veebiteenus, mis töötab väga hästi, reageerimisajaga mõne millisekundi, kuid see ei skaleeru üldse. Samuti võib esineda halvasti toimiv veebirakendus, mille reageerimine võtab mõne sekundi, kuid kümnete tuhandete samaaegsete kasutajatega toimetulemiseks suureneb see kümnete võrra. Suure jõudluse ja mastaapsuse kombinatsioon on aga väga võimas kombinatsioon. Suure jõudlusega rakendused kasutavad ressursse üldiselt säästlikult ja teenindavad seega tõhusamalt rohkem samaaegseid kasutajaid serveris, vähendades sellega kulusid.

CPU ja I/O ülesanded

Lõpuks on andmetöötluses alati kahte tüüpi ülesandeid: I/O ja CPU jaoks. Päringute vastuvõtmine Interneti kaudu (võrgu I/O), failide teenindamine (võrgu ja ketta sisend/väljund), andmebaasiga suhtlemine (võrk ja ketta sisend/väljund) on kõik sisend-/väljundtegevused. Mõned andmebaasipäringud võivad olla veidi protsessorimahukad (sorteerimine, miljoni tulemuse keskmine arvutamine jne). Enamik veebirakendusi on piiratud maksimaalse võimaliku I/O-ga ja protsessorit kasutatakse harva täisvõimsusel. Kui näete, et mõni I/O ülesanne kasutab palju protsessorit, on see tõenäoliselt märk kehvast rakenduse arhitektuurist. See võib tähendada, et protsessori ressursse raisatakse protsesside haldamisele ja konteksti vahetamisele – ja see pole täiesti kasulik. Kui teete näiteks pilditöötlust, helifailide teisendamist või masinõpet, vajab rakendus võimsaid protsessori ressursse. Kuid enamiku rakenduste puhul see nii ei ole.

Lisateave serveriarhitektuuride kohta

  1. I osa: iteratiivne arhitektuur
  2. II osa. Kahvelserverid
  3. III osa. Fork-eelsed serverid
  4. IV osa. Täitelõimedega serverid
  5. V osa. Lõimega serverid
  6. VI osa. Pol-põhine arhitektuur
  7. VII osa. epoll põhinev arhitektuur

Allikas: www.habr.com

Lisa kommentaar