Linux hálózati alkalmazások teljesítménye. Bevezetés

A webalkalmazásokat ma már mindenhol használják, és az összes szállítási protokoll közül a HTTP oroszlánrészét foglalja el. A webalkalmazások fejlesztésének árnyalatait tanulmányozva a legtöbben nagyon kevés figyelmet fordítanak arra az operációs rendszerre, ahol ezek az alkalmazások ténylegesen futnak. A fejlesztés (Dev) és az üzemeltetés (Ops) szétválasztása csak rontott a helyzeten. De a DevOps kultúra térnyerésével a fejlesztők egyre felelőssé válnak alkalmazásaik felhőben történő futtatásáért, ezért nagyon hasznos számukra, ha alaposan megismerkednek az operációs rendszer háttérrendszerével. Ez különösen akkor hasznos, ha egy rendszert több ezer vagy több tízezer egyidejű kapcsolatra próbál telepíteni.

A webszolgáltatások korlátai nagyon hasonlóak más alkalmazások korlátaihoz. Legyen szó terheléselosztóról vagy adatbázis-kiszolgálóról, ezeknek az alkalmazásoknak mindegyike hasonló problémákkal küzd a nagy teljesítményű környezetben. Ezen alapvető korlátok megértése és általánosságban leküzdése segít Önnek értékelni webalkalmazásai teljesítményét és méretezhetőségét.

Ezt a cikksorozatot fiatal fejlesztők kérdéseire válaszolva írom, akik jól tájékozott rendszertervezők szeretnének lenni. Lehetetlen világosan megérteni a Linux alkalmazásoptimalizálási technikákat anélkül, hogy belemerülnénk az operációs rendszer szintű működésük alapjaiba. Bár sokféle alkalmazás létezik, ebben a sorozatban inkább webalapú alkalmazásokat szeretnék felfedezni, nem pedig asztali alkalmazásokat, például böngészőt vagy szövegszerkesztőt. Ez az anyag azoknak a fejlesztőknek és építészeknek szól, akik szeretnék megérteni, hogyan működnek a Linux vagy Unix programok, és hogyan lehet őket felépíteni a nagy teljesítmény érdekében.

A Linux az szerver szoba operációs rendszert, és az alkalmazásai leggyakrabban ezen az operációs rendszeren futnak. Bár azt mondom, hogy "Linux", legtöbbször nyugodtan feltételezhető, hogy általában az összes Unix-szerű operációs rendszerre gondolok. A kísérő kódot azonban nem teszteltem más rendszereken. Tehát, ha érdekel a FreeBSD vagy az OpenBSD, az eredmények eltérőek lehetnek. Amikor megpróbálok valami Linux-specifikusat, rámutatok.

Bár ezt a tudást felhasználhatja egy alkalmazás létrehozásához a semmiből, és az tökéletesen optimalizált lesz, jobb, ha ezt nem teszi meg. Ha új webszervert ír C vagy C++ nyelven szervezete üzleti alkalmazásához, akkor ez lehet az utolsó munkanapja. Azonban ezen alkalmazások szerkezetének ismerete segít a meglévő programok kiválasztásában. Összehasonlíthatja a folyamatalapú rendszereket a szálalapú rendszerekkel, valamint az eseményalapú rendszerekkel. Meg fogja érteni és értékelni fogja, hogy az Nginx miért teljesít jobban, mint az Apache httpd, miért tud egy Tornado alapú Python alkalmazás több felhasználót kiszolgálni, mint egy Django alapú Python alkalmazás.

ZeroHTTPd: oktatóeszköz

ZeroHTTPd egy webszerver, amit a semmiből írtam C nyelven, mint tanítási eszközt. Nincs külső függősége, beleértve a Redishez való hozzáférést. Saját Redis eljárásainkat futtatjuk. További részletekért lásd alább.

Bár az elméletről hosszasan tárgyalhatnánk, nincs jobb, mint kódot írni, futtatni, és az összes szerverarchitektúrát összehasonlítani egymással. Ez a legkézenfekvőbb módszer. Ezért minden modellt használva egy egyszerű ZeroHTTPd webszervert fogunk írni: folyamatalapú, szál alapú és eseményalapú. Nézzük meg ezeket a szervereket, és nézzük meg, hogyan teljesítenek egymáshoz képest. A ZeroHTTPd egyetlen C fájlban valósul meg. Az esemény alapú szerver tartalmazza Uthash, egy nagyszerű hash tábla megvalósítás, amely egyetlen fejlécfájlban érkezik. Más esetekben nincsenek függőségek, hogy ne bonyolítsák a projektet.

A kódban sok megjegyzés található, amelyek segítenek megérteni. Mivel egy egyszerű webszerver néhány sornyi kóddal, a ZeroHTTPd a webfejlesztés minimális kerete is. Korlátozott funkcionalitással rendelkezik, de képes statikus fájlok és nagyon egyszerű "dinamikus" oldalak kiszolgálására. Azt kell mondanom, hogy a ZeroHTTPd arra alkalmas, hogy megtanuljuk, hogyan készítsünk nagy teljesítményű Linux-alkalmazásokat. Általában véve a legtöbb webszolgáltatás várja a kéréseket, ellenőrzi és feldolgozza azokat. Pontosan ezt fogja tenni a ZeroHTTPd. Ez a tanulás eszköze, nem a termelés. Nem kiváló hibakezelésben, és nem valószínű, hogy a legjobb biztonsági gyakorlatokkal büszkélkedhet (ó, igen, használtam strcpy) vagy a C nyelv okos trükkjei.De remélem jól teszi a dolgát.

Linux hálózati alkalmazások teljesítménye. Bevezetés
ZeroHTTPd kezdőlap. Különféle fájltípusokat képes kiadni, beleértve a képeket is

Vendégkönyv jelentkezés

A modern webes alkalmazások általában nem korlátozódnak statikus fájlokra. Összetett interakciókat folytatnak különböző adatbázisokkal, gyorsítótárakkal stb. Így létrehozunk egy egyszerű webalkalmazást "Vendégkönyv" néven, ahol a látogatók bejegyzéseket hagynak a nevük alatt. A vendégkönyv tárolja a korábban hagyott bejegyzéseket. Az oldal alján látogatószámláló is található.

Linux hálózati alkalmazások teljesítménye. Bevezetés
Webalkalmazás "Vendégkönyv" ZeroHTTPd

A látogatószámláló és a vendégkönyv bejegyzései a Redisben tárolódnak. A Redis-szel való kommunikációhoz saját eljárások vannak megvalósítva, ezek nem függenek a külső könyvtártól. Nem vagyok nagy rajongója a homebrew kód bevezetésének, ha vannak nyilvánosan elérhető és jól tesztelt megoldások. De a ZeroHTTPd célja a Linux teljesítményének és a külső szolgáltatásokhoz való hozzáférésnek a tanulmányozása, miközben a HTTP kérések kiszolgálása komoly hatással van a teljesítményre. Teljes mértékben ellenőriznünk kell a Redis-szel folytatott kommunikációt minden szerverarchitektúránkban. Egyes architektúrákban blokkoló hívásokat, másokban eseményalapú eljárásokat alkalmazunk. Külső Redis-ügyfélkönyvtár használata nem biztosítja ezt a vezérlést. Ezenkívül a mi kis Redis kliensünk csak néhány funkciót hajt végre (kulcs lekérése, beállítása és növelése; tömb lekérése és hozzáfűzése). Ráadásul a Redis protokoll rendkívül elegáns és egyszerű. Nem is kell külön tanítani. Már az a tény, hogy a protokoll körülbelül száz sornyi kódban elvégzi az összes munkát, mutatja, mennyire átgondolt.

A következő ábra azt mutatja, hogy mit csinál az alkalmazás, amikor a kliens (böngésző) kéri /guestbookURL.

Linux hálózati alkalmazások teljesítménye. Bevezetés
Hogyan működik a vendégkönyv alkalmazás

Amikor egy vendégkönyv-oldalt kell kiadni, egy hívás érkezik a fájlrendszerhez, hogy beolvassa a sablont a memóriába, és három hálózati hívás a Redis felé. A sablonfájl tartalmazza a fenti képernyőképen látható oldal HTML-tartalmának nagy részét. A tartalom dinamikus részének speciális helyőrzői is vannak: bejegyzések és látogatószámláló. Ezeket a Redistől megkapjuk, beillesztjük az oldalra, és a kliensnek teljes formájú tartalommal látjuk el. A Redis harmadik hívása elkerülhető, mert a Redis az új kulcsértéket adja vissza, amikor növeli. Az aszinkron eseményalapú architektúrával rendelkező szerverünknél azonban a sok hálózati hívás jó teszt tanulási célokra. Tehát a látogatók számának Redis visszatérési értékét eldobjuk, és külön hívással lekérdezzük.

Szerver architektúrák ZeroHTTPd

A ZeroHTTPd hét változatát készítjük azonos funkcionalitással, de eltérő architektúrával:

  • Ismétlődő
  • Fork szerver (kérelemenként egy gyermekfolyamat)
  • Elágazás előtti szerver (folyamatok elágazása)
  • Szerver végrehajtási szálakkal (kérelemenként egy szál)
  • Szerver szál előtti létrehozással
  • Építészet alapú poll()
  • Építészet alapú epoll

Az egyes architektúrák teljesítményét úgy mérjük, hogy HTTP-kérésekkel töltjük be a szervert. De ha nagyon párhuzamos architektúrákat hasonlítunk össze, a lekérdezések száma nő. Háromszor teszteljük, és kiszámítjuk az átlagot.

Vizsgálati módszertan

Linux hálózati alkalmazások teljesítménye. Bevezetés
ZeroHTTPd terhelési tesztelés beállítása

Fontos, hogy a tesztek futtatásakor ne minden komponens fusson ugyanazon a gépen. Ebben az esetben az operációs rendszer további ütemezési többletköltséggel jár, mivel az összetevők versengenek a CPU-ért. Ennek a gyakorlatnak az egyik legfontosabb célja az operációs rendszer többletterhelésének mérése az egyes kiválasztott szerverarchitektúrákon. További változók hozzáadása káros lesz a folyamatra. Ezért a fenti képen látható beállítás működik a legjobban.

Mit csinálnak ezek a szerverek?

  • load.unixism.net: Itt futunk ab, Apache Benchmark segédprogram. Előállítja a szerverarchitektúránk teszteléséhez szükséges terhelést.
  • nginx.unixism.net: Néha egy szerverprogram egynél több példányát is szeretnénk futtatni. Ehhez a megfelelő beállításokkal rendelkező Nginx szerver terheléselosztóként működik ab szerver folyamatainkhoz.
  • zerohttpd.unixism.net: Itt hét különböző architektúrán futtatjuk szerverprogramjainkat, egyenként.
  • redis.unixism.net: Ez a szerver a Redis démont futtatja, ahol a vendégkönyv bejegyzései és a látogatószámlálók tárolódnak.

Minden szerver ugyanazon a processzormagon fut. Az ötlet az, hogy értékeljük az egyes architektúrák maximális teljesítményét. Mivel minden szerverprogramot ugyanazon a hardveren tesztelnek, ez az összehasonlítás alapja. A tesztbeállításom a Digital Oceantől bérelt virtuális szerverekből áll.

Mit mérünk?

Különböző mutatókat mérhet. Az egyes architektúrák teljesítményét egy adott konfigurációban úgy értékeljük, hogy a szervereket különböző párhuzamossági szintű kérésekkel töltjük be: a terhelés 20-ról 15 000 egyidejű felhasználóra nő.

Teszteredmények

A következő diagram a kiszolgálók teljesítményét mutatja különböző architektúrákon a párhuzamosság különböző szintjein. Az y tengely a kérések száma másodpercenként, az x tengely a párhuzamos kapcsolatok.

Linux hálózati alkalmazások teljesítménye. Bevezetés

Linux hálózati alkalmazások teljesítménye. Bevezetés

Linux hálózati alkalmazások teljesítménye. Bevezetés

Az alábbi táblázat az eredményeket tartalmazza.

kérések másodpercenként

párhuzamosság
ismétlődő
Villa
elővilla
folyó
előzetes streaming
szavazás
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
nagy terjedés
2138

5000
-
nagy terjedés
1600
1100
2519
-
2235

8000
-
-
1200
nagy terjedés
2451
-
2100

10
-
-
nagy terjedés
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

A grafikonon és a táblázaton látható, hogy 8000 egyidejű kérés felett már csak két játékosunk maradt: a pre-fork és az epoll. A terhelés növekedésével a szavazáson alapuló szerver rosszabbul teljesít, mint a streaming szerver. A szál-előkészítési architektúra méltó versenytársa az epollnak, bizonyítva, hogy a Linux kernel milyen jól ütemez nagyszámú szálat.

ZeroHTTPd forráskód

ZeroHTTPd forráskód itt. Minden architektúrához külön könyvtár tartozik.

ZeroHTTPd │ ├── 01_iteratív │ ├── fő.c ├── 02_elágazás │ ├── fő.c ├── 03_előfork.─────04. 05_ menetfűzés │ ├── fő.c ├── 06_előfűzés │ ├── main.c ├── 07_poll │ ├── main.c ├── XNUMX_epoll │ │ ─── nyilvánossá tétele ────le. ├── index .html │ └── tux png └── sablonok └── vendégkönyv └── index.html

Az összes architektúrához tartozó hét könyvtáron kívül még kettő található a legfelső szintű könyvtárban: a nyilvános és a sablonok. Az első az index.html fájlt és az első képernyőkép képét tartalmazza. Más fájlokat és mappákat is elhelyezhet oda, és a ZeroHTTPd-nek gond nélkül ki kell szolgálnia ezeket a statikus fájlokat. Ha a böngésző elérési útja megegyezik a nyilvános mappában lévő elérési úttal, akkor a ZeroHTTPd ebben a könyvtárban keresi az index.html fájlt. A vendégkönyv tartalma dinamikusan generálódik. Csak egy kezdőlapja van, tartalma pedig a 'templates/guestbook/index.html' fájlon alapul. A ZeroHTTPd könnyedén hozzáad dinamikus oldalakat a bővítéshez. Az ötlet az, hogy a felhasználók sablonokat adhatnak ehhez a könyvtárhoz, és szükség szerint kiterjeszthetik a ZeroHTTPd-t.

Mind a hét szerver felépítéséhez futtassa make all a legfelső szintű könyvtárból – és az összes build ebben a könyvtárban fog megjelenni. A végrehajtható fájlok a nyilvános és sablonkönyvtárakat keresik abban a könyvtárban, ahonnan elindultak.

Linux API

Nem kell jól ismernie a Linux API-t ahhoz, hogy megértse a cikksorozatban található információkat. Mindazonáltal azt javaslom, hogy olvasson többet erről a témáról, mivel az interneten számos referenciaforrás található. Bár a Linux API-k több kategóriáját érintjük, elsősorban a folyamatokra, szálakra, eseményekre és a hálózati veremre fogunk összpontosítani. A Linux API-ról szóló könyvek és cikkek mellett a mana elolvasását is javaslom a rendszerhívásokhoz és a használt könyvtári funkciókhoz.

Teljesítmény és méretezhetőség

Egy megjegyzés a teljesítményről és a méretezhetőségről. Elméletileg nincs kapcsolat közöttük. Lehet egy webszolgáltatás, ami nagyon jól működik, néhány ezredmásodperces válaszidővel, de egyáltalán nem skálázódik. Hasonlóképpen előfordulhat, hogy vannak gyengén teljesítő webalkalmazások, amelyeknek néhány másodpercig tart a válaszadás, de tízezrekkel skálázódik, hogy több tízezer egyidejű felhasználót kezeljen. A nagy teljesítmény és a méretezhetőség kombinációja azonban nagyon erős kombináció. A nagy teljesítményű alkalmazások általában takarékosan használják fel az erőforrásokat, és így hatékonyabban szolgálják ki a kiszolgáló több egyidejű felhasználóját, csökkentve a költségeket.

CPU és I/O feladatok

Végül a számítástechnikában mindig kétféle feladat lehetséges: I/O és CPU. A kérések fogadása az interneten keresztül (hálózati I/O), a fájlok kiszolgálása (hálózati és lemezes I/O), az adatbázissal való kommunikáció (hálózati és lemezes I/O) mind I/O tevékenység. Egyes adatbázis-lekérdezések kissé CPU-igényesek lehetnek (rendezés, millió eredmény átlagolása stb.). A legtöbb webalkalmazást a lehető legnagyobb I/O korlátozza, és a processzort ritkán használják teljes kapacitással. Ha azt látja, hogy néhány I/O feladat sok CPU-t használ, az valószínűleg a rossz alkalmazásarchitektúra jele. Ez azt jelentheti, hogy a CPU erőforrásait a folyamatkezelésre és a környezetváltásra pazarolják – és ez nem teljesen hasznos. Ha például képfeldolgozást, hangfájlok konvertálását vagy gépi tanulást végez, akkor az alkalmazás erőteljes CPU-erőforrásokat igényel. De a legtöbb alkalmazás esetében ez nem így van.

További információ a szerverarchitektúrákról

  1. I. rész: Iteratív architektúra
  2. rész II. Fork szerverek
  3. rész III. Fork előtti szerverek
  4. rész IV. Szerverek végrehajtási szálakkal
  5. V. rész. Előszálas szerverek
  6. rész VI. Pol alapú architektúra
  7. VII. rész. epoll alapú architektúra

Forrás: will.com

Hozzászólás