Performanse Linux mrežne aplikacije. Uvod

Web aplikacije se sada koriste svuda, a među svim transportnim protokolima, HTTP zauzima lavovski udio. Prilikom proučavanja nijansi razvoja web aplikacija, većina ljudi posvećuje vrlo malo pažnje operativnom sistemu na kojem te aplikacije zapravo rade. Razdvajanje razvoja (Dev) i operacija (Ops) samo je pogoršalo situaciju. Ali sa porastom DevOps kulture, programeri postaju odgovorni za pokretanje svojih aplikacija u oblaku, tako da je za njih veoma korisno da se temeljno upoznaju sa pozadinom operativnog sistema. Ovo je posebno korisno ako pokušavate da implementirate sistem za hiljade ili desetine hiljada istovremenih veza.

Ograničenja u web servisima su vrlo slična onima u drugim aplikacijama. Bilo da su u pitanju balanseri opterećenja ili serveri baze podataka, sve ove aplikacije imaju slične probleme u okruženju visokih performansi. Razumijevanje ovih osnovnih ograničenja i općenito kako ih prevladati pomoći će vam da ocijenite performanse i skalabilnost vaših web aplikacija.

Ovu seriju članaka pišem kao odgovor na pitanja mladih programera koji žele da postanu dobro informisani sistemski arhitekti. Nemoguće je jasno razumjeti tehnike optimizacije Linux aplikacija bez zarona u osnove njihovog funkcioniranja na razini operativnog sistema. Iako postoji mnogo vrsta aplikacija, u ovoj seriji želim istražiti web-bazirane aplikacije, a ne desktop aplikacije kao što su pretraživač ili uređivač teksta. Ovaj materijal je namijenjen programerima i arhitektima koji žele razumjeti kako Linux ili Unix programi funkcioniraju i kako ih strukturirati za visoke performanse.

Linux je server room operativni sistem, a najčešće vaše aplikacije rade na ovom OS. Iako kažem "Linux", većinu vremena možete sa sigurnošću pretpostaviti da mislim na sve operativne sisteme slične Unixu općenito. Međutim, nisam testirao prateći kod na drugim sistemima. Dakle, ako ste zainteresovani za FreeBSD ili OpenBSD, vaši rezultati mogu varirati. Kada pokušam nešto specifično za Linux, to istaknem.

Iako ovo znanje možete koristiti da napravite aplikaciju od nule i ona će biti savršeno optimizirana, najbolje je to ne raditi. Ako napišete novi web server u C ili C++ za poslovnu aplikaciju vaše organizacije, ovo može biti vaš posljednji dan na poslu. Međutim, poznavanje strukture ovih aplikacija pomoći će pri odabiru postojećih programa. Moći ćete da uporedite sisteme zasnovane na procesima sa sistemima zasnovanim na nitima, kao i sa sistemima zasnovanim na događajima. Razumjet ćete i cijeniti zašto Nginx radi bolje od Apache httpd, zašto Python aplikacija zasnovana na Tornadu može poslužiti više korisnika u poređenju sa Python aplikacijom zasnovanom na Djangu.

ZeroHTTPd: Alat za učenje

ZeroHTTPd je web server koji sam napisao od nule u C-u kao nastavno sredstvo. Nema vanjske zavisnosti, uključujući pristup Redis-u. Mi vodimo vlastite Redis procedure. Pogledajte ispod za više detalja.

Iako bismo mogli opširno raspravljati o teoriji, nema ništa bolje od pisanja koda, njegovog pokretanja i međusobnog poređenja svih serverskih arhitektura. Ovo je najočitija metoda. Stoga ćemo napisati jednostavan ZeroHTTPd web server koristeći svaki model: baziran na procesu, na nitima i na događaju. Hajde da pogledamo svaki od ovih servera i vidimo kako se oni međusobno ponašaju. ZeroHTTPd je implementiran u jednu datoteku C. Server baziran na događajima uključuje uthash, odlična implementacija hash tablice koja dolazi u jednom zaglavlju. U drugim slučajevima nema zavisnosti, kako ne bi komplicirali projekat.

Postoji mnogo komentara u kodu koji će vam pomoći da shvatite. Budući da je jednostavan web server u nekoliko linija koda, ZeroHTTPd je također minimalni okvir za web razvoj. Ima ograničenu funkcionalnost, ali je sposoban posluživati ​​statične datoteke i vrlo jednostavne "dinamičke" stranice. Moram reći da je ZeroHTTPd dobar za učenje kako kreirati Linux aplikacije visokih performansi. Uglavnom, većina web servisa čeka zahtjeve, provjerava ih i obrađuje. To je upravo ono što će ZeroHTTPd učiniti. Ovo je alat za učenje, a ne proizvodnju. Nije odličan u rukovanju greškama i malo je vjerovatno da će se pohvaliti najboljim sigurnosnim praksama (o da, koristio sam strcpy) ili pametnim trikovima jezika C. Ali nadam se da dobro radi svoj posao.

Performanse Linux mrežne aplikacije. Uvod
ZeroHTTPd početna stranica. Može prikazati različite tipove datoteka uključujući slike

Aplikacija za knjigu gostiju

Moderne web aplikacije obično nisu ograničene na statične datoteke. Imaju složene interakcije sa raznim bazama podataka, keš memorijama itd. Tako ćemo kreirati jednostavnu web aplikaciju pod nazivom "Knjiga gostiju" u kojoj posjetitelji ostavljaju unose pod svojim imenima. Knjiga gostiju pohranjuje ranije ostavljene unose. Tu je i brojač posjetitelja na dnu stranice.

Performanse Linux mrežne aplikacije. Uvod
Web aplikacija "Knjiga gostiju" ZeroHTTPd

Brojač posjetitelja i unosi u knjigu gostiju pohranjeni su u Redis-u. Za komunikaciju sa Redis-om implementiraju se vlastite procedure koje ne zavise od eksterne biblioteke. Nisam veliki obožavatelj uvođenja homebrew koda kada postoje javno dostupna i dobro testirana rješenja. Ali svrha ZeroHTTPd je proučavanje performansi Linuxa i pristupa vanjskim uslugama, dok posluživanje HTTP zahtjeva ima ozbiljan utjecaj na performanse. Moramo u potpunosti kontrolirati komunikaciju s Redis-om u svakoj od naših serverskih arhitektura. U nekim arhitekturama koristimo blokirajuće pozive, u drugima koristimo procedure zasnovane na događajima. Upotreba eksterne Redis klijentske biblioteke neće pružiti ovu kontrolu. Uz to, naš mali Redis klijent obavlja samo nekoliko funkcija (dobijanje, postavljanje i povećanje ključa; dobijanje i dodavanje nizu). Osim toga, Redis protokol je izuzetno elegantan i jednostavan. Ne morate to čak ni posebno podučavati. Sama činjenica da protokol obavlja sav posao u oko stotinu linija koda pokazuje koliko je dobro osmišljen.

Sljedeća slika pokazuje šta aplikacija radi kada klijent (pretraživač) zatraži /guestbookURL.

Performanse Linux mrežne aplikacije. Uvod
Kako funkcioniše aplikacija za knjigu gostiju

Kada je potrebno izdati stranicu knjige gostiju, postoji jedan poziv sistemu datoteka za čitanje šablona u memoriju i tri mrežna poziva Redis-u. Datoteka šablona sadrži većinu HTML sadržaja za stranicu na slici iznad. Postoje i posebni čuvari mjesta za dinamički dio sadržaja: postovi i brojač posjetitelja. Dobijamo ih od Redisa, ubacujemo ih na stranicu i pružamo klijentu potpuno formiran sadržaj. Treći poziv Redis-u se može izbjeći jer Redis vraća novu vrijednost ključa kada se poveća. Međutim, za naš server, koji ima asinkronu arhitekturu zasnovanu na događajima, mnogo mrežnih poziva je dobar test za potrebe učenja. Stoga odbacujemo Redis povratnu vrijednost broja posjetitelja i ispitujemo je posebnim pozivom.

Arhitektura servera ZeroHTTPd

Gradimo sedam verzija ZeroHTTPd-a sa istom funkcionalnošću ali različitim arhitekturama:

  • Iterativno
  • Fork server (jedan podređeni proces po zahtjevu)
  • Pre-fork server (pre-forkiranje procesa)
  • Server sa nitima izvršenja (jedna nit po zahtjevu)
  • Server sa kreiranjem pre-thread-a
  • Arhitektura zasnovana poll()
  • Arhitektura zasnovana epoll

Mjerimo performanse svake arhitekture tako što učitavamo server HTTP zahtjevima. Ali kada se porede visoko paralelne arhitekture, povećava se broj upita. Testiramo tri puta i izračunavamo prosjek.

Metodologija testiranja

Performanse Linux mrežne aplikacije. Uvod
ZeroHTTPd podešavanje testiranja opterećenja

Važno je da prilikom izvođenja testova sve komponente ne rade na istoj mašini. U ovom slučaju, OS ima dodatne troškove planiranja jer se komponente takmiče za CPU. Mjerenje nadopterećenja operativnog sistema svake od odabranih serverskih arhitektura jedan je od najvažnijih ciljeva ove vježbe. Dodavanje više varijabli će postati štetno za proces. Stoga postavka na gornjoj slici najbolje funkcionira.

Šta radi svaki od ovih servera?

  • load.unixism.net: Ovo je mjesto gdje trčimo ab, Apache Benchmark uslužni program. Generiše opterećenje potrebno za testiranje arhitekture naših servera.
  • nginx.unixism.net: Ponekad želimo da pokrenemo više od jedne instance serverskog programa. Da biste to učinili, Nginx server s odgovarajućim postavkama radi kao balansator opterećenja koji dolazi ab na naše serverske procese.
  • zerohttpd.unixism.net: Ovdje pokrećemo naše serverske programe na sedam različitih arhitektura, jedan po jedan.
  • redis.unixism.net: Ovaj server pokreće Redis demon, gdje se pohranjuju unosi u knjigu gostiju i brojači posjetitelja.

Svi serveri rade na istom procesorskom jezgru. Ideja je da se procijene maksimalne performanse svake arhitekture. Pošto su svi serverski programi testirani na istom hardveru, ovo je osnova za poređenje. Moje testno podešavanje se sastoji od virtuelnih servera iznajmljenih od Digital Oceana.

Šta merimo?

Možete mjeriti različite indikatore. Procenjujemo performanse svake arhitekture u datoj konfiguraciji tako što učitavamo servere zahtevima na različitim nivoima paralelizma: opterećenje raste sa 20 na 15 istovremenih korisnika.

Rezultati ispitivanja

Sljedeći grafikon prikazuje performanse servera na različitim arhitekturama na različitim nivoima paralelizma. Y-osa je broj zahtjeva u sekundi, x-osa su paralelne veze.

Performanse Linux mrežne aplikacije. Uvod

Performanse Linux mrežne aplikacije. Uvod

Performanse Linux mrežne aplikacije. Uvod

Ispod je tabela sa rezultatima.

zahtjeva u sekundi

paralelizam
iterativno
viljuška
pre-fork
streaming
pre-streaming
anketa
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
veliki namaz
2138

5000
-
veliki namaz
1600
1100
2519
-
2235

8000
-
-
1200
veliki namaz
2451
-
2100

10
-
-
veliki namaz
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Iz grafikona i tabele se može vidjeti da iznad 8000 istovremenih zahtjeva imamo još samo dva igrača: pre-fork i epoll. Kako se opterećenje povećava, server baziran na anketama radi lošije od streaminga. Arhitektura pre kreiranja niti je dostojan konkurent epoll-u, dokaz koliko dobro Linux kernel planira veliki broj niti.

ZeroHTTPd izvorni kod

ZeroHTTPd izvorni kod ovdje. Za svaku arhitekturu postoji poseban direktorij.

ZeroHTTPd │ ├── 01_iterative │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking │ ├── main.c ├── main.c ├── 04. 05_prethreading │ ├── main.c ├── 06_poll │ ├── main.c ├── 07_epoll │ └── main.c ├── Makefile ├─ html ├── javno │ ├─── tu│ ├─── tu│ ├─── . png └── šabloni └── knjiga gostiju └── index.html

Pored sedam direktorija za sve arhitekture, postoje još dva u direktoriju najviše razine: public i templates. Prvi sadrži datoteku index.html i sliku sa prvog snimka ekrana. Tamo možete staviti druge fajlove i fascikle, a ZeroHTTPd bi te statičke fajlove trebao poslužiti bez ikakvih problema. Ako se putanja u pretraživaču poklapa sa putanjom u javnoj mapi, tada ZeroHTTPd traži datoteku index.html u ovom direktoriju. Sadržaj za knjigu gostiju se generira dinamički. Ima samo početnu stranicu, a njegov sadržaj je zasnovan na datoteci 'templates/guestbook/index.html'. ZeroHTTPd lako dodaje dinamičke stranice za proširenje. Ideja je da korisnici mogu dodati šablone u ovaj direktorij i proširiti ZeroHTTPd prema potrebi.

Za izgradnju svih sedam servera, pokrenite make all iz direktorija najviše razine - i sve verzije će se pojaviti u ovom direktoriju. Izvršne datoteke traže javne i predloške direktorije u direktoriju iz kojeg su pokrenute.

Linux API

Ne morate biti dobro upućeni u Linux API da biste razumjeli informacije u ovoj seriji članaka. Međutim, preporučujem da pročitate više o ovoj temi; postoji mnogo referentnih izvora na Internetu. Iako ćemo se dotaknuti nekoliko kategorija Linux API-ja, naš fokus će biti prvenstveno na procesima, nitima, događajima i mrežnom stogu. Osim knjiga i članaka o Linux API-ju, također preporučujem čitanje mana za sistemske pozive i korištene funkcije biblioteke.

Performanse i skalabilnost

Jedna napomena o performansama i skalabilnosti. Teoretski, nema veze između njih. Možete imati web servis koji radi vrlo dobro, s vremenom odziva od nekoliko milisekundi, ali se uopće ne povećava. Isto tako, može postojati web aplikacija sa lošim performansama kojoj je potrebno nekoliko sekundi da odgovori, ali se povećava za desetine kako bi obradila desetine hiljada istovremenih korisnika. Međutim, kombinacija visokih performansi i skalabilnosti je vrlo moćna kombinacija. Aplikacije visokih performansi uglavnom štedljivo koriste resurse i na taj način efikasno opslužuju više istovremenih korisnika na serveru, smanjujući troškove.

CPU i I/O zadaci

Konačno, u računarstvu uvijek postoje dvije moguće vrste zadataka: za I/O i CPU. Prijem zahtjeva preko Interneta (mrežni I/O), posluživanje datoteka (mrežni i disk I/O), komunikacija sa bazom podataka (mrežni i disk I/O) su sve I/O aktivnosti. Neki upiti za bazu podataka mogu biti malo CPU-intenzivni (sortiranje, u prosjeku milion rezultata, itd.). Većina web aplikacija ograničena je maksimalnim mogućim I/O, a procesor se rijetko koristi punim kapacitetom. Kada vidite da neki I/O zadatak koristi puno CPU-a, to je najvjerovatnije znak loše arhitekture aplikacije. To može značiti da se CPU resursi troše na upravljanje procesima i promjenu konteksta - a to nije sasvim korisno. Ako radite nešto kao što je obrada slika, konverzija audio datoteka ili strojno učenje, aplikacija zahtijeva moćne CPU resurse. Ali za većinu aplikacija to nije slučaj.

Saznajte više o arhitekturi servera

  1. Dio I: Iterativna arhitektura
  2. Dio II. Fork serveri
  3. Dio III. Pre-fork serveri
  4. dio IV. Serveri sa nitima izvršenja
  5. Dio V. Pred-threaded serveri
  6. Dio VI. Arhitektura zasnovana na Pol
  7. Dio VII. arhitektura zasnovana na epoll

izvor: www.habr.com

Dodajte komentar