Linux tinklo programos našumas. Įvadas

Dabar žiniatinklio programos naudojamos visur, o tarp visų transporto protokolų liūto dalį užima HTTP. Tyrinėdami žiniatinklio programų kūrimo niuansus, dauguma žmonių labai mažai dėmesio skiria operacinei sistemai, kurioje šios programos iš tikrųjų veikia. Plėtros (Dev) ir operacijų (Ops) atskyrimas situaciją tik pablogino. Tačiau augant DevOps kultūrai kūrėjai tampa atsakingi už savo programų paleidimą debesyje, todėl jiems labai naudinga susipažinti su operacinės sistemos užpakaline dalimi. Tai ypač naudinga, jei bandote įdiegti sistemą tūkstančiams ar dešimčių tūkstančių vienu metu jungiamų jungčių.

Žiniatinklio paslaugų apribojimai yra labai panašūs į kitų programų apribojimus. Nesvarbu, ar tai būtų apkrovos balansavimo įrenginiai, ar duomenų bazių serveriai, visos šios programos turi panašių problemų didelio našumo aplinkoje. Suprasdami šiuos pagrindinius apribojimus ir apskritai, kaip juos įveikti, galėsite įvertinti savo žiniatinklio programų našumą ir mastelio keitimą.

Rašau šią straipsnių seriją atsakydamas į jaunų kūrėjų, norinčių tapti gerai informuotais sistemų architektais, klausimus. Neįmanoma aiškiai suprasti „Linux“ programų optimizavimo metodų, nesigilinus į jų veikimo operacinės sistemos lygmeniu pagrindus. Nors yra daugybė programų tipų, šioje serijoje noriu ištirti žiniatinklio programas, o ne darbalaukio programas, pvz., naršyklę ar teksto rengyklę. Ši medžiaga skirta kūrėjams ir architektams, norintiems suprasti, kaip veikia Linux arba Unix programos ir kaip jas struktūrizuoti, kad jos veiktų aukštai.

Linux yra serverio patalpa operacinę sistemą ir dažniausiai jūsų programos veikia šioje OS. Nors sakau „Linux“, dažniausiai galite drąsiai manyti, kad turiu omenyje visas „Unix“ tipo operacines sistemas apskritai. Tačiau aš neišbandžiau pridedamo kodo kitose sistemose. Taigi, jei jus domina FreeBSD arba OpenBSD, rezultatas gali būti kitoks. Kai bandau ką nors specifinio „Linux“, atkreipiu dėmesį į tai.

Nors galite panaudoti šias žinias kurdami programą nuo nulio ir ji bus puikiai optimizuota, geriau to nedaryti. Jei rašote naują žiniatinklio serverį C arba C++ savo organizacijos verslo programai, tai gali būti paskutinė jūsų darbo diena. Tačiau šių programų struktūros žinojimas padės pasirinkti esamas programas. Galėsite palyginti procesu pagrįstas sistemas su gijų sistemomis, taip pat įvykiais pagrįstomis sistemomis. Suprasite ir įvertinsite, kodėl „Nginx“ veikia geriau nei „Apache httpd“, kodėl Tornado pagrįsta „Python“ programa gali aptarnauti daugiau vartotojų, palyginti su „Django“ pagrįsta „Python“ programa.

ZeroHTTPd: mokymosi įrankis

ZeroHTTPd yra žiniatinklio serveris, kurį rašiau nuo nulio C kaip mokymo priemonė. Ji neturi išorinių priklausomybių, įskaitant prieigą prie Redis. Atliekame savo Redis procedūras. Daugiau informacijos rasite toliau.

Nors apie teoriją galėtume diskutuoti ilgai, nėra nieko geriau nei parašyti kodą, jį paleisti ir lyginti visas serverių architektūras tarpusavyje. Tai akivaizdžiausias būdas. Todėl mes parašysime paprastą ZeroHTTPd žiniatinklio serverį naudodami kiekvieną modelį: pagrįstą procesu, gijomis ir įvykiais. Pažiūrėkime kiekvieną iš šių serverių ir pažiūrėkime, kaip jie veikia vienas su kitu. „ZeroHTTPd“ yra įdiegtas viename C faile. Įvykis pagrįstas serveris utašas, puikus maišos lentelės įgyvendinimas, pateikiamas viename antraštės faile. Kitais atvejais nėra jokių priklausomybių, kad nebūtų apsunkintas projektas.

Kode yra daug komentarų, padedančių suprasti. Kadangi ZeroHTTPd yra paprastas kelių kodo eilučių žiniatinklio serveris, jis taip pat yra minimali žiniatinklio kūrimo sistema. Jo funkcionalumas yra ribotas, tačiau jis gali aptarnauti statinius failus ir labai paprastus „dinaminius“ puslapius. Turiu pasakyti, kad „ZeroHTTPd“ yra naudinga norint išmokti kurti didelio našumo „Linux“ programas. Apskritai dauguma žiniatinklio paslaugų laukia užklausų, jas tikrina ir apdoroja. Būtent tai padarys ZeroHTTPd. Tai mokymosi, o ne gamybos įrankis. Jis nėra puikus klaidų valdymo srityje ir vargu ar gali pasigirti geriausia saugumo praktika (o taip, aš naudojau strcpy) arba sumanios C kalbos gudrybės, bet tikiuosi, kad ji gerai atlieka savo darbą.

Linux tinklo programos našumas. Įvadas
ZeroHTTPd pagrindinis puslapis. Jis gali išvesti įvairių tipų failus, įskaitant vaizdus

Svečių knygos programa

Šiuolaikinės žiniatinklio programos paprastai neapsiriboja statiniais failais. Jie turi sudėtingą sąveiką su įvairiomis duomenų bazėmis, talpyklomis ir pan. Taigi mes sukursime paprastą žiniatinklio programą pavadinimu „Svečių knyga“, kurioje lankytojai paliks įrašus savo vardais. Svečių knygoje saugomi anksčiau palikti įrašai. Puslapio apačioje taip pat yra lankytojų skaitiklis.

Linux tinklo programos našumas. Įvadas
Interneto programa „Svečių knyga“ ZeroHTTPd

Lankytojų skaitiklis ir svečių knygos įrašai saugomi Redis. Ryšiams su Redis yra įdiegtos savos procedūros, kurios nepriklauso nuo išorinės bibliotekos. Nesu didelis „Homebrew“ kodo diegimo gerbėjas, kai yra viešai prieinamų ir gerai patikrintų sprendimų. Tačiau „ZeroHTTPd“ tikslas yra ištirti „Linux“ našumą ir prieigą prie išorinių paslaugų, o HTTP užklausų aptarnavimas turi rimtą poveikį našumui. Turime visiškai kontroliuoti ryšį su Redis kiekvienoje savo serverio architektūroje. Kai kuriose architektūrose naudojame blokuojančius skambučius, kitose – įvykiais pagrįstas procedūras. Naudojant išorinę Redis kliento biblioteką šis valdymas nebus suteiktas. Be to, mūsų mažasis „Redis“ klientas atlieka tik keletą funkcijų (rakto gavimas, nustatymas ir padidinimas; masyvo gavimas ir pridėjimas). Be to, Redis protokolas itin elegantiškas ir paprastas. Jums net nereikia to specialiai mokyti. Pats faktas, kad protokolas visą darbą atlieka maždaug šimte kodo eilučių, rodo, kaip jis gerai apgalvotas.

Toliau pateiktame paveikslėlyje parodyta, ką programa daro, kai klientas (naršyklė) prašo /guestbookURL.

Linux tinklo programos našumas. Įvadas
Kaip veikia svečių knygos programa

Kai reikia išleisti svečių knygos puslapį, vienas iškvietimas į failų sistemą nuskaito šabloną į atmintį ir trys tinklo skambučiai į Redis. Šablono faile yra didžioji dalis puslapio HTML turinio aukščiau esančioje ekrano kopijoje. Taip pat yra specialių vietos rezervavimo ženklų, skirtų dinaminei turinio daliai: įrašams ir lankytojų skaitikliui. Juos gauname iš Redis, įdedame į puslapį ir pateikiame klientui pilnai suformuotą turinį. Trečio skambučio į Redis galima išvengti, nes padidinus Redis grąžina naują rakto reikšmę. Tačiau mūsų serveriui, turinčiam asinchroninę įvykiais pagrįstą architektūrą, daug tinklo skambučių yra geras išbandymas mokymosi tikslais. Taigi atmetame Redis grąžinimo reikšmę apie lankytojų skaičių ir užklausiame atskiru skambučiu.

Serverio architektūros ZeroHTTPd

Kuriame septynias ZeroHTTPd versijas su tokiomis pačiomis funkcijomis, bet skirtingomis architektūromis:

  • Iteratyvus
  • Šakės serveris (vienai užklausai vienas antrinis procesas)
  • „Pre-fork“ serveris (išankstinis procesų išsišakojimas)
  • Serveris su vykdymo gijomis (viena gija užklausoje)
  • Serveris su išankstiniu gijos kūrimu
  • Architektūra pagrįsta poll()
  • Architektūra pagrįsta epoll

Kiekvienos architektūros našumą vertiname įkeldami serverį HTTP užklausomis. Tačiau lyginant labai lygiagrečias architektūras, užklausų skaičius didėja. Testuojame tris kartus ir apskaičiuojame vidurkį.

Testavimo metodika

Linux tinklo programos našumas. Įvadas
ZeroHTTPd apkrovos testavimo sąranka

Svarbu, kad atliekant bandymus visi komponentai neveiktų toje pačioje mašinoje. Tokiu atveju OS patiria papildomų planavimo išlaidų, nes komponentai konkuruoja dėl procesoriaus. Išmatuoti kiekvienos pasirinktos serverio architektūros operacinės sistemos sąnaudas yra vienas iš svarbiausių šio pratimo tikslų. Pridėjus daugiau kintamųjų, procesas bus žalingas. Todėl aukščiau esančiame paveikslėlyje esantis nustatymas veikia geriausiai.

Ką daro kiekvienas iš šių serverių?

  • load.unixism.net: čia mes bėgame ab, „Apache Benchmark“ įrankis. Jis generuoja apkrovą, reikalingą mūsų serverių architektūroms išbandyti.
  • nginx.unixism.net: Kartais norime paleisti daugiau nei vieną serverio programos egzempliorių. Norėdami tai padaryti, „Nginx“ serveris su atitinkamais parametrais veikia kaip apkrovos balansavimo priemonė, gaunama iš ab mūsų serverio procesams.
  • zerohttpd.unixism.net: čia mes paleidžiame serverio programas septyniose skirtingose ​​architektūrose, po vieną.
  • redis.unixism.net: Šiame serveryje veikia Redis demonas, kuriame saugomi svečių knygos įrašai ir lankytojų skaitikliai.

Visi serveriai veikia tame pačiame procesoriaus branduolyje. Idėja yra įvertinti maksimalų kiekvienos architektūros našumą. Kadangi visos serverio programos testuojamos ta pačia technine įranga, tai yra palyginimo pagrindas. Mano bandomąją sąranką sudaro virtualūs serveriai, nuomojami iš „Digital Ocean“.

Ką mes matuojame?

Galite matuoti įvairius rodiklius. Mes vertiname kiekvienos architektūros našumą tam tikroje konfigūracijoje, įkeldami serverius su užklausomis skirtingais lygiagretumo lygiais: apkrova išauga nuo 20 iki 15 000 vienu metu veikiančių vartotojų.

Bandymų rezultatai

Toliau pateiktoje diagramoje parodytas skirtingų architektūrų serverių veikimas skirtingais lygiagretumo lygiais. Y ašis – užklausų skaičius per sekundę, x ašis – lygiagrečios jungtys.

Linux tinklo programos našumas. Įvadas

Linux tinklo programos našumas. Įvadas

Linux tinklo programos našumas. Įvadas

Žemiau yra lentelė su rezultatais.

užklausų per sekundę

sutapimas
pasikartojantis
šakutė
išankstinė šakutė
transliacija
išankstinis transliavimas
apklausa
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
didelis plitimas
2138

5000
-
didelis plitimas
1600
1100
2519
-
2235

8000
-
-
1200
didelis plitimas
2451
-
2100

10
-
-
didelis plitimas
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Iš grafiko ir lentelės matyti, kad virš 8000 vienu metu pateiktų užklausų turime tik du žaidėjus: pre-fork ir epoll. Didėjant apkrovai, apklausomis pagrįstas serveris veikia blogiau nei srautinio perdavimo serveris. Išankstinė gijų kūrimo architektūra yra vertas epoll konkurentas, liudijantis, kaip gerai Linux branduolys suplanuoja daugybę gijų.

ZeroHTTPd šaltinio kodas

ZeroHTTPd šaltinio kodas čia. Kiekvienai architektūrai yra atskiras katalogas.

ZeroHTTPd │ ├── 01_iteratyvus │ ├── pagrindinis.c ├── 02_išsišakojimas │ ├── pagrindinis.c ├── 03_──────────── _-asis skaitymas │ ├── pagrindinis.c ├── 04_išankstinis siūlymas │ ├── main.c ├── 05_apklausa │ ├── main.c ├── 06_epoll │ │ │─── Viešas failas.c ──├── ├── indeksas │ └── tux png └── šablonai └── svečių knyga └── index.html

Be septynių visų architektūrų katalogų, aukščiausio lygio kataloge yra dar du: viešasis ir šablonai. Pirmajame yra failas index.html ir vaizdas iš pirmosios ekrano kopijos. Ten galite įdėti kitus failus ir aplankus, o „ZeroHTTPd“ turėtų pateikti tuos statinius failus be jokių problemų. Jei kelias naršyklėje sutampa su keliu viešajame aplanke, tada ZeroHTTPd šiame kataloge ieško failo index.html. Svečių knygos turinys generuojamas dinamiškai. Jis turi tik pagrindinį puslapį, o jo turinys pagrįstas failu „templates/guestbook/index.html“. „ZeroHTTPd“ lengvai prideda dinaminius puslapius, kad būtų galima išplėsti. Idėja yra ta, kad vartotojai gali pridėti šablonų į šį katalogą ir prireikus išplėsti ZeroHTTPd.

Norėdami sukurti visus septynis serverius, paleiskite make all iš aukščiausio lygio katalogo – ir visi versijos bus rodomi šiame kataloge. Vykdomieji failai ieško viešųjų ir šablonų katalogų kataloge, iš kurio jie paleisti.

Linux API

Nereikia gerai išmanyti Linux API, kad suprastumėte šios straipsnių serijos informaciją. Tačiau aš rekomenduoju paskaityti daugiau šia tema, internete yra daug informacijos šaltinių. Nors paliesime kelias Linux API kategorijas, daugiausia dėmesio skirsime procesams, gijomis, įvykiams ir tinklo dėkui. Be knygų ir straipsnių apie „Linux“ API, taip pat rekomenduoju perskaityti „mana“ apie sistemos iškvietimus ir naudojamas bibliotekos funkcijas.

Našumas ir mastelio keitimas

Viena pastaba apie našumą ir mastelį. Teoriškai tarp jų nėra jokio ryšio. Galite turėti labai gerai veikiančią žiniatinklio paslaugą, kurios atsako laikas yra kelios milisekundės, tačiau ji visiškai nesikeičia. Taip pat gali būti prastai veikianti žiniatinklio programa, kuriai reaguoti reikia kelių sekundžių, tačiau jos dydis padidėja dešimtimis, kad galėtų apdoroti dešimtis tūkstančių vienu metu esančių vartotojų. Tačiau didelio našumo ir mastelio derinys yra labai galingas derinys. Didelio našumo programos paprastai taupiai naudoja išteklius ir taip efektyviai aptarnauja daugiau vienu metu esančių serverio vartotojų, sumažindamos išlaidas.

CPU ir I/O užduotys

Galiausiai, kompiuterijoje visada yra dviejų tipų užduotys: I/O ir CPU. Užklausų gavimas internetu (tinklo I/O), failų aptarnavimas (tinklo ir disko įvestis/išvestis), bendravimas su duomenų baze (tinklas ir disko įvestis/išvestis) yra visa įvesties/išvesties veikla. Kai kurios duomenų bazės užklausos gali šiek tiek užimti CPU (rūšiavimas, milijono rezultatų vidurkis ir tt). Daugumą žiniatinklio programų riboja didžiausias įmanomas I/O, o procesorius retai naudojamas visu pajėgumu. Kai matote, kad kuri nors įvesties / išvesties užduotis naudoja daug procesoriaus, greičiausiai tai yra prastos programos architektūros ženklas. Tai gali reikšti, kad procesoriaus resursai eikvojami procesų valdymui ir konteksto perjungimui – ir tai nėra visiškai naudinga. Jei atliekate kažką panašaus į vaizdo apdorojimą, garso failų konvertavimą ar mašininį mokymąsi, programai reikia galingų procesoriaus išteklių. Tačiau daugeliui programų taip nėra.

Sužinokite daugiau apie serverių architektūras

  1. I dalis: Iteratyvioji architektūra
  2. II dalis. Šakės serveriai
  3. III dalis. Išankstiniai serveriai
  4. IV dalis. Serveriai su vykdymo gijomis
  5. V dalis. Išankstiniai gijų serveriai
  6. VI dalis. Pol pagrindu sukurta architektūra
  7. VII dalis. epoll pagrįsta architektūra

Šaltinis: www.habr.com

Добавить комментарий