Sziasztok!
Végre érdekes szakmai téma került elő. Annak persze nem örülök, hogy emiatt túlórázni kell, de a nyomozós téma mindig érdekes.
Méricskélünk egy 2.4-es httpd-t mert nem hozza a rendszer az elvárt számokat. A cél 5-6000 egyidejű kérés kiszolgálása. Egyelőre nézzük a sima statikus fájl kiszolgálást - pl. 500k-s fájl - vagy a terheléselosztó üzemet mod_proxy-val.
A legtöbb helyen azt írják, hogy válts nginx-re, traefik-re ami persze egy lehetséges út, de most egyelőre az a mondás, hogy amíg nem tuti, hogy az Apache a szűk keresztmetszet, addig ne váltsunk.
Kíváncsi lennék a Ti tapasztalataitokra!
update: Közben kiderült, hogy hálózati gebasz biztosan van, mert azonos hálózatban lévő gépről 10000 szálon headless JMeterrel hiba nélkül lefutott a teszt.
Hozzászólások
>A cél 5-6000 egyidejű kérés kiszolgálása
Mi az, hogy egyidejű, és mi az ami nem működik? Ha _tényleg_ egyszerre, egyetlen pillanatban jön be ennyi kérés, akkor egy részét eldobja még válaszadás előtt? Vagy timeoutra fut?
Ha belegondolsz eleve fából vaskarika, hogy _egyszerre_ jön 5-6000 kérés, mert a hálózati interfészen egymás után kell hogy jöjjenek :-).
Szerintem két kérdés is van ebben: Hány kapcsolat lehet aktív egyidejűen? Ugye HTTP2 esetén egyetlen kapcsolatban több HTTP lekérés is kiszolgálható, és hosszabb ideig is nyitva lehet a kapcsolat, mint egyetlen lekérés ideje.
Hány lekérést tud kiszolgálni a szerver egy adott idő alatt? Ebből számolható, hogy nagyjából mekkora átlagterhelés az, amit úgy tud kiszolgálni, hogy senki nem kap hibát.
JMeterből megy a kérés rampup nélkül (ügyfél ennyit határozott meg, hogy el kell bírni). Ha egy terhelő gép hálózatát kitömjük, akkor több gépről futtatjuk. A cél, hogy 0% hibával timeout-on belül jöjjön válasz.
Most azt látjuk, hogy olyan 2000 környékén már hibázgat, egy-két kérés timeout-ol. SSL nélkül jobban muzsikál valamivel ami nyilván logikus. Egy idő után van SYN queue meg accept queue hiba netstat -s alapján.
> Ugye HTTP2 esetén egyetlen kapcsolatban több HTTP lekérés is kiszolgálható, és hosszabb ideig is nyitva lehet a kapcsolat, mint egyetlen lekérés ideje.
Sőt HTTP/1.1 esetén is. (Épp ránéztem egy házi fejlesztésű reverse-proxyra, azt mondja, hogy a kimenő kapcsolata 321 napja él, továbbított kérések száma 141815)
Szerintem amirol o beszelt az a multiplexing, ami bejott a HTTP2-vel, te pedig egy keepalive-ot latsz.
És ugye ezek azok a dolgok amikről jó tudni és explicite kell kapcsolni amikor 5-6000 _egyidejű_ letöltést szeretnénk szimulálni lehetőleg kevesebb mint 5-6000 gépről.
Gábriel Ákos
Melyik worker? Szerintem mindegyiknél lehet maxrequest/maxconnection stb. limiteket állítani, onnantól meg csak erőforrás kérdése.. ha valóban egyidőben esnek be a kérések, és közben mást is csinál a szerver, tcp szinten is lehet/kellhet tuningolni, pl. fin timeout, local port range, stb.
Próbáltuk mindkettővel, Prefork lényegesen lassabb.
Az jo mert 3 van ;). Eventet hasznaljatok.
Ilyen terhelések mellett event alapú aszinkron működés kell, minimalizálni kell az OS overhead-jét. Az nginx is így működik, innen indult az egész: https://en.wikipedia.org/wiki/C10k_problem.
Szia,
Szerintem is zsakutca az apache (es lehet a linux is), bar ebbol a leirasbol nem derul ki mi lesz majd a vegso feladata es milyen hw-en, de egy tipp, mi amikor reszeljuk a rendszerunket azt ugyanazon HW cfg-n csinaljuk es monitorozzuk, hogy a rendszer mennyi Gbps-t kepes kitolni per cpu% (pl.: ha ez az ertek 2 akkor 100% cpu usage mellet elmeletileg 200Gbps-t tudhat, persze ez nem mindig linearisa alakul, de egy jo alap), termeszetesen ehhez szukseges, hogy ugyanugy tudd reprodukalni a terhelest (itt nekem szerencsem van, mert csak raengedem a usereket es hajra:) ).
Legyen itt egy "tapasztalat" is, amennyiben static fileokat akarsz kiszolgani es kell https is, akkor kezdetnek linux helyett fbsd es nginx,sendfile(),ktls, ha meg akarsz rajta faszazni akkor cx6/7 nic, amivel tudsz tls offloadot.
Köszi! Szerintem ha megpendítem a freebsd átállást, itt páran leesnek a székről :)
Mivel egy spring/angular webapp kiszolgálása a cél, statikus kiszolgálás és proxy is kell, de a tényleges kiszolgálást hátra lehet tolni a terheléselosztó mögé, csak a https végződtetés mindenképpen a terheléselosztón van. Kérdés van-e érdemi különbség, ha az LB csak proxyzza a statikus tartalmat, vagy maga szolgálja ki.
Miért van a https terminalasa az LB-n mindenkeppen?
Akkor mondjuk úgy, hogy ha nem muszáj akkor ezen nem változtatnék.
Mitől tud többet ugyanaz a vas FreeBSD-vel, mint Linuxszal? Nem kötekvésképpen kérdezem, hanem valóban érdekel. A területen műkedvelő vagyok csak, érdekel, de nem a szakterületem. Olvastam pár cikket, meg néztem benchmarkokat, úgy emlékszem, hogy a legtöbbet kiszolgáló megoldások io_uring-re épülnek és ilyen mini HTTP implementációk. Az oprendszert eddig nem is néztem.
A TLS offload-ra rákerestem (ezt néztem meg: https://www.nvidia.com/content/dam/en-zz/Solutions/networking/ethernet-… ), ez úgy működik, hogy a handshake után a szimmetrikus titkosítást tudja a "HW" megcsinálni, de a handshake még CPU-ból megy? Vagy azt is tudja az NVIDIA vasa valahogy?
> Mitől tud többet ugyanaz a vas FreeBSD-vel, mint Linuxszal? Nem kötekvésképpen kérdezem
ugye (ha elolvastad a C10K cikket) 2 dologtol fugg a performance (azonos worker mellett): thread kezeles es event (select) kezeles.
ezek kernelbeli dolgok, igy a bsd es linux kozott hatalmas kulonbsegek lehetnek. regen voltak is, de szerintem mar elmult. remeljuk :)
az se mind1, hogy az user es kernel space kozotti valtas mennyi ido. foleg az elmult evek cpu bugjai es az azokra erkezett workaroundok miatt (amik ezt az idot drasztikusan megnoveltek) izgi. nem veletlen kiserleteznek kernelben futo webszerverrel es userspaceben futo tcp stackkel, hogy ezt az ide-oda valtogatast elkeruljek...
Pont itt írtam a stack-et egy válaszban lentebb, pl az kisebb. Így több thread elfér a memóriában. Ez pl az egyik fő akadálya a sok thread-nek. De azon felül egyéb dolgok is memóriát foglalnak egy threaddel kapcsolatban (ha a stack mérete szabályozható is).
azert 6000 keresnel meg nem a memoria szokott a szuk keresztmetszet lenni... legalabbis remlejuk nem egy rapsberry pi-n fog futni mindez ;)
A linuxban pl a default beállítás 8 Mb. 6000 threadnél az 48 Gb. (plusz erre jön rá pár rendszer-adatszerkezet, meg további memória terület, amit a thread használhat (nem tudom mi van, ami esetleg nem megosztott)) Ezért is szoktak threadpoolt használni (meg azért mert a thread-et létrehozni is költséges), és mondjuk 50 thread-et használnak, ami sorra veszi a feladatokat. Vagy ez az egyik oka a virtual thread-eknek mint lehetőségnek pl java-ban (szerintem java 21-től), az OS thread az nagyon költséges. (Meg ott ugye blokkolásnál is tud más futni bonyolítás nélkül.)
Igen, a kiszolgálónak érdemes non blocking IO-t tudni, és az epollnál is jobb az uring. Szálból annyi kell, ahány végrehajtási egység (virtuális mag) van, annál többet általában értelmetlen indítani, kivéve ha van blocking. De blocking az ne legyen, ha az ember sok usert akar kiszolgálni :-) De akkor még mindig ott a virtuális thread, ahogy írtad, csak arra meg fel kell készíteni a szoftvereket, a többség szerintem nem tudja. Én például Jetty-t szeretek használni (de csak intranetes kevés useres dolgokat csináltam eddig), és ott van lehetőség blokkolni egy kérést végrehajtó szálat, és lehet jelezni a szervernek, hogy ez itt most várni fog, nyisson helyette egy másikat. De ha sok ilyet csinálunk, akkor a sok várakozó szál tényleg okozhat RAM problémát. Kevés userrel elmegy, sok userrel már nem árt máshogy gondolkodni.
A thread stack méretét szerintem a program beállíthatja, nem kötelező az OS defaultot használni.
Ezek amiket írsz már mind meghaladott problémák Linuxon is. Nem ismerem mélyen az apache-t, hogy ott is már megoldották-e mindet.
Ugye, az egyidejűn van a hangsúly.
Ezek mind olyan problémák, amiket írtam, amiket figyelembe kell venni. Én sem ismerem az apache-ot, régen használtuk, passz...
A másik, hogy nem is biztos, hogy az apache lesz a szűk keresztmetszet, ha az egy proxy lesz végül. :)
És lehet, hogy ami fájl kiszolgálással működik majd, ott a proxy-val (minden egyéb tényezőt leszámítva is) teljesen mások lesznek a tapasztalatok.
Az 5-6000 egyidejű kérés először is várakozási sor kérdése, az meg konfiguráció (hálózat, kernel) kérdése, a RAM-ba belefér az tuti. Az idő, ami alatt ledarál ennyi választ, az meg annak a kérdése, hogy mi a feladat. Én TLS és web kiszolgálás benchmarkokat néznék, abból láthatod, hogy mi a reálisan elérhető. Én úgy tudom, hogy össze lehet olyan szervert rakni, ami simán lenyom 6000 kérés választ 1 másodperc alatt is. Pláne ha a kiszolgálandó tartalom RAM-ba van cache-elve. De a feladat nem jól specifikált, mert az egy dolog, hogy egyszerre jönnek be a kérések, de az nincsen benne, hogy mi az elvárt válaszidő. Az Angularban jó, hogy a kliens oldalon dolgozik főleg, és egy előre elkészített de nagy javascriptet kell csak kiszolgálni a HTML mellé (AFAIK).
Ha az összerakott teszt rendszer hibázik, akkor annak valami konfigurációs problémája van: ahelyett, hogy sorba állítva várakoztatná a kiszolgálatlan kéréseket például le akarja forkolni az N+1-dik processzt, aminek már nincs elég RAM.
Ha nincsen semmi apache specifikus a rendszeretekben, akkor én is azzal kezdeném, hogy a netes infók alapján a lehető legmodernebb, legtöbbet használt szervert telepíteném, ami manapság IMHO az nginx. Az nginx nem forkolgat, és epoll-t használ belül ha jól tudom emiatt elég jó teljesítményt nyújt. Vannak még gyorsabb io_uring alapú szerverek, de azokat talán több munka életre lehellni és inkább a TLS lesz a szűk keresztmetszet úgyis, nem a userspace/kernel átmenetek száma. Én nginx-el mérnék elsőre, és ki kell jönnie, hogy röhögve kiszolgál párezer kérést egy másodpercen belül.
Például itt találtam egy írást benchmarkokról, 2020-as, és az jött ki, hogy egy 8 magos szerver 4400 TLS/sec-et tudott kiszolgálni: https://www.f5.com/pdf/report/NGINX-SSL-Performance_2020-revision.pdf Úgyhogy annyira nem lesz röhögős az 5000 kérés/sec, de meg lehet valósítani kellően erős vassal manapság.
A traefik-et sem ismerem, de itt van a listámban hogy meg kellene nézni, állítólag nagyon jó kis eszköz.
Én egy ilyen feladat esetén összehasonlítanám őket, és belemennék a paraméterezésükbe is, legalább olyan szinten, hogy megnézni a default-okat, és át kell-e állítani valamit.
Jó kis cucc, kényelmesebb konfigolni mint az Apache-t pl. bár ez nyílván ízlés dolga.
Ami nekem lejött, hogy cloudos környezetben azért szeretik mert mindenféle helyről tud konfigot olvasni, nem csak fájlból hanem pl. kubernetes annotációkból is.
Még egy dolog: Oké, ez világos. Vagy-vagy. A kérdés az, hogy a várakozási sor + a kevesebb feldolgozó thread, az pont a párhuzamos feldolgozás ellen dolgozik. A gyakorlatban 6000 thread az nagyon sok szerintem (elindítani is sok, szerintem ilyet nem is szoktak egy átlagos rendszerben), a várakozási sor pedig (kevesebb feldolgozó threaddel) "várakoztat". Tehát a szokásos kérdés, hogy mi a legjobb beállítás... (ha vertikálisan kell skálázni a gépet, lehet, ez egy nagyobb gép mint 16Gb RAM, amit írt valahol a kérdező, de ezt kell kipróbálni.). És proxy lesz a legvégén, nem egy fájlletöltés. Ott a háttér rendszer lesz még kérdés.
Ha az egyik szál blokkolva van, IO-ra vár, akkor lehet csinálni mást, így a több szálnak van értelme. - kérdés, hogy meddig van értelme emelni.
>Ha az egyik szál blokkolva van, IO-ra vár, akkor lehet csinálni mást
Úgy képzelem, hogy a statikus fájlok kiszolgálása esetén a fájlok nagyon hamar valami hot cache-ben végzik RAM-ban - akár az nginx processzben, akár a kernelben, de valahol a RAM-ban lesz a válasz minden kérésre. Ezek a szálak nem fognak blokkolni.
Amikor pedig továbbhív az nginx egy másik kérésen keresztül a valódi web szerver felé, akkor ezek non-blocking io-ban lesznek végződtetve, ami szintén azt jelenti, hogy nem lesz blokkolás.
(Olyan szervert nem használnék, ami nem tud nonblocking IO-val proxyzni, mert ott valóban kiszámíthatatlan a szükséges szálak/processzek száma.)
Tehát ha jól van megtervezve a rendszer, akkor nincsen benne blokkolás, ergó nincs értelme több szálat indítani mint amennyi végrehajtó szál a CPU-ban van.
Nem tudom, hogy milyen módon kell mérni ezt apache vagy nginx esetén, de valahogy ezeket a statisztikákat meg kell szerezni, hogy mennyi a várakozás és mennyi az aktív CPU használat. És ebből lehet következtetni, hogy mennyi az ideális száma a szálaknak. Egy alternatív megközelítés lehet, hogy simán bekonfolod a CPU szálak számára és reménykedsz, hogy jó lesz, mert 99%, hogy jó lesz. Ha meg nem jó, akkor allokálsz egy fix mennyiséget, amit addig növelsz míg jó nem lesz. A lényeg, hogy legyen egy fix korlát, amivel még stabil a rendszer, hogy emiatt ne rohadjon le. Nem feltétlenül kell ezt túlgondolni.
+1
Statikus fájl kiszolgálása szerintem itt nem lesz releváns (nem akarom túlgondolni a feladatot, de már megtettem. :)), mert azt írta, hogy végül proxy kell. Ha továbbhív a "valódi webszerver" felé, az gondolom egy alkalmazás felé hív tovább, ott szintén kérdés a blokkolás, és a szálak száma. De a teljes rendszerről semmit nem tudunk, tehát végül is ez mindegy.
Úgy tudom, hogy statikus fájlokra a proxyt sokszor úgy értik, hogy cache proxy. Amikor először kiszolgálja, akkor a headerekből látja, hogy cache-elhető a tartalom, megjegyzi és legközelebb már emlékezetből mondja fel. nginx-en be lehet állítani ilyet, az biztos.
Arra kell(het) plusz szálat fenntartani ha a kérések egy része i/o bound (várakozik bármire) lesz.
Amíg minden non-blocking átrohan a rendszeren addig valóban ahány core annyi szál és kész.
Core-ok száma x2 - x4 nem szokott rossz kiindulás lenni.
Gábriel Ákos
szerencsés esetben, ha minden async (így nincs i/o bound), akkor senki nem várakozik mert a worst-case az, hogy majd valamikor máskor lesz eredménye a dolognak. Itt viszont valóban az a jó stratégia, ha pontosan annyi szál van, mint amennyi core (A tökéletes állapot). x2-x4 esetén ezt a performance-t a context change miatt fogod agyonverni. Sőt, nagy tervezésekkel lehet ezt még cifrázni :)
// Happy debugging, suckers
#define true (rand() > 10)
A logolás (és adott esetben a dns lekérdezés a logoláshoz) is simán adhat i/o boundot.
Gábriel Ákos
Ezek közül egyik feladat sem követeli meg azt, hogy nem lehet aszinkron módon intézni
// Happy debugging, suckers
#define true (rand() > 10)
az io_uring -el óvatosan, a google legutolsó nagy linux kernel auditján az igen kellemetlen bugok és exploitok 60%-nál volt összefüggés vele. Azóta az io_uring az Android/Chrome OS/Google cloud szervereken is tíltva van, a docker pedig default-ból tíltja ezeket a syscall-okat
// Happy debugging, suckers
#define true (rand() > 10)
Köszi, nem tudtam! Eddig csak szemeztem vele, remélem meghegesztik jóra mikorra úgy lesz, hogy tényleg dolgozni is fogok vele.
Ahány projekten foglalkoztam optimalizációval (nem web szerver témában, hanem teljesen más dolgokon), mindenhol beleütköztem abba, hogy a userspace-kernel átmenet elképesztő brutál bottleneck, amit architekturális újragombolás nélkül meg se lehet oldani. Ilyen 10-100x gyorsulásokról lehet beszélni ott, ahol sok volt az interprocessz kommunikáció és átírtuk a kernelen keresztüli kommunikációt például shared memory+spin lockra.
Az io_uring azt a problémát oldja meg, hogy ne kelljen minden átviteli blokk miatt belehívni a kernelbe, és sok kicsi adatblokk minta esetén szerintem hasonló nagyságrendű hatása lehet. De mondom, nem dolgoztam vele, csak doksikat néztem meg benchmarkokat. Jó tudni amit írsz!
Ha most kellene valami ilyesmit fejlesztenem, akkor egészen biztosan libuv irányába mennék (korábban jó választásnak tűnt, akkor ezt használtam) és azóta már belefutottam, hogy van io_uring támogatása is. Szóval ha egyszer végre kikerekedik az uring, akkor gondolom minimális igazítással lehet aktiválni
// Happy debugging, suckers
#define true (rand() > 10)
Async sendfile, illetve rack tcp stack, ami nem okozott kisebb terhelest a szerveren, de user oldalon nott a bitrate.
Biztos jo (lesz) az io_uring, de en meg nem nagyon lattam pl nginx-et ami tudja is hasznalni, kicsit jelenleg olyan topic ez nekem mint a quic/http3.
TLS offload,
"HW-offload (the focus of this guide) – handshake and error handling are performed in software. Packets are encrypted/decrypted in hardware. In this case, there is an additional offload from the kernel to the hardware. "
src: https://docs.nvidia.com/doca/sdk/nvidia+tls+offload+guide/index.html#sr…
Köszi, jó tudni! Az alternatív TCP stackről sem hallottam még.
Ezt a benchmarkot szoktam nézegetni időről időre: https://www.techempower.com/benchmarks/#hw=ph&test=plaintext§ion=da… Mivel funkciókészlet nincs előírva tudtommal, ezért a győztesek sokszor minimál frameworkok, amik éppen annyit tudnak ami a benchmarkhoz kell. De így is érdekes, mert a plaintext eredmények teteje azt mutatja, hogy mit lehet ma egy Linux kernel alatt kihozni, nyilván azért van egyben ennyire az élboly, mert elmentek az optimalizálhatóság határáig.
Amikor legutóbb nézegettem, akkor volt a leggyorsabbak között is olyan, ami állítása szerint production ready. És úgy rémlik, hogy mindegyik io_uring-et használ, mert csak azzal lehet ebbe a sebességtartományba belépni Linux alapon. Az nginx teljesítménye 22.6%-a győztesének, szerintem ez a különbség alapvetően az io_uring-ből adódik, epoll alapon ennyit lehet elérni (én is úgy tudom, hogy nincs io_uring alapú nginx). Sajnos a használt kernel API nincs benne a táblázatban, annak utána kell olvasgatni, hogy megtudjuk. A jetty 14% körül van: nekem eddig belefért ez a kompromisszum, hogy Javában fejleszthessek.
Sajnos ebben a benchmarkban csak Linuxos megvalósítások versenyeznek úgy látom. Érdekes lenne egy FreeBSD vs Linux összehasonlítás egyazon vason.
A plaintext eredményeket nyilván úgy kell nézni, hogy ha akármilyen funkciót aláteszünk egy ilyen szervernek, akkor 99%, hogy azonnal a funkció lesz a szűk keresztmetszet, tehát élesben kihasználni a top teljesítményeket nem nagyon lehet. De hallottam már olyat, hogy ahol komolyan veszik a teljesítményt ott C kódból generálják a HTML-t :-)
Szerk.: lehet, hogy mégse kell a top eredményhez io_uring, mert a 99.7%-os wizzardo-http a doksik szerint epoll alapú.
> ott C kódból generálják a HTML-t
manapsag inkabb JS-bol generaljak, a kliens gepen...
szervereken inkabb csak static file kiszolgalas (bar azt meg ki kene tolni CDN-re) es valamilyen API backend (python vagy nodejs, esetleg java) fut.
Ez attól is függ, hogy milyen környezetben.
Szerintem mérjétek meg, és hasonlítsátok össze mással is.
Lehet egyébként paraméterezni, próbáljátok meg finomhangolni, stb... Attól is függ, hogy mennyit engedtek, mennyi idő után dobja el a kérést, stb...
5-6000 kérés az reális? Milyen alkalmazás, felhasználók kattintgatnak? Egy hatalmas alkalmazás esetén is lehet, hogy a ténylegesen egyidejű request szám mondjuk 20 db (csak a hasamra ütöttem) Közben lehet, hogy 5000-en használják egyszerre.
Erre nincs ráhatásom, az az ukász, hogy 5000 párhuzamos kérést vigyen el. Ezért érdekelne, hogy látott-e már valaki olyan Apache-t ami erre képes volt és ha igen, milyen erőforrás felhasználás mellett?
most én igazából tőled olyanokat várnék, hogy a jelenlegi vas egy x fizikai processzoros 1-2-4 socket, x core y thread
z GB ram, NVME háttértárral.
500 connect esetén így alakul a terhelés
1000 connect esetén amúgy
2000-nél már kezdenek gondok lenni, akkor emígy
arról elképzelésem nincsen, hogy az SSL lib-ben használt titkosítást éppen tudja-e hw offload-olni a CPU...
Ezt tudom, de ezért is kezdtem úgy a topicot, hogy tapasztalatokra vagyok elsősorban kíváncsi, hogy egyáltalán reálisan elérhető-e a cél?
Virtuális gép, 16G ram 4 vcpu, diszkről nincs infóm.
Igen, reálisan elvárható.
500 párhuzamos gépen fut majd, felhőben 100Gbit/s-os hálózaton, vagy egy pc-n a főnök irodájában az íróasztal mellett, a leselejtezett desktop gépén, ami ki lett nevezve egy szervernek? Most szándékosan írtam a két végletet. Tehát így értelmetlen a kérdés, mert nincs szofveres korlát.
Próbájátok ki, hogy ahol mennie kell, vagy hasonló környezetben mit teljesít (olyan helyen, ami alapján már tudtok becsülni), jó-e nektek, és hasonlítsátok össze egyéb más megoldásokkal is, pl nginx, vagy más. Ha van bármilyen mérésetek, akkor meg lehet még nézni a beállításokat, hogy lehetne tunningolni. A végén látni fogjátok, hogy mit kellene változtatni, akár konfigot, akár környezetet, és milyen irányba kellene menni.
De amúgy nekem gyanús ez a követelmény, mi az, aminek 5000 párhuzamos request-et kell tudnia? Tehát ezt a kérdést is tedd fel. Pl egy olyan alkalmazásban, amit felhasználók hajtanak meg, nem biztos, hogy van 5000 párhuzamos kérés. Szokásos hiba szokott lenni, hogy húúú, 5000 felhasználó volt bejelentkezve, akkor 5000 párhuzamos kérést kell tudni. Nem, mert nem egyszerre kattintanak, és nézik a képernyőt. (ez csak egy példa)
Szerk: egyébként sok minden van, pl kiosztható erőforrások, vagy a sok thread egyszerre nagyon sok memóriát tud foglalni, mert rengeteg adat van tárolva egy thread-ről. Nem véletlen kezdték el használni java alatt is a virtual thread-eket, pont az ilyen párhuzamos kérések feldolgozása miatt. Pl minden thread-nek 8Mb stack-je van linux alatt, akkor az 5000 thread 40Gb memória - csak az, hogy thread-ed van: https://ariadne.space/2021/06/25/understanding-thread-stack-sizes-and-h…
De persze ettől még lehet egy alkalmazást úgy skálázni egy környezetben, hogy tudja az 5000 párhuzamos kérést, vagy többet is (más megközelítéssel, pl. nem egy gépen).
Most azt írtad: Egyelőre nézzük a sima statikus fájl kiszolgálást - Nagyon nem mindegy, hogy végül mit nézünk meg, mert függ attól is, hogy ami egy előtét webszerver mögött van, az hogy működik, ott a szálak hogy blokkolják egymást, várnak egyéb megosztott erőforrásra stb...
Köszi a threades cikket, ezt jó tudni!
A statikus fájl kiszolgálást azért írtam mert egyelőre azzal is akadnak problémák ilyen kérésszámnál ezért első körben ezt oldanánk meg.
uazt a kb 500kbyte-os file-t akarja letölteni az 5000 kliens? Ezt ramdisk-ből próbálod, ugye?
az 5000 kliens az 1 gépről van szimulálva, vagy 5db gépről 1000-1000 kliens?
Szarul megírt :D
Fedora 41, Thinkpad x280
ezt ismered?
http://www.kegel.com/c10k.html
igazabol a problema gyokere a select() illetve annak korlatai. vannak alternativai (pl. epoll, kqueue), anno ebben volt a bsd es az nginx jobb mert elobb implementaltak, de ma mar a linux/apache is tudja ugyanazt, csak jol kell bekonfolni. vszinu nem eleg az apacsot, hanem a kernelt (sysctl) is kell allitgatni ekkora terheleshez.
Nem ismertem, megnézem köszi!
Az 5-6000 egyidejü kérés önmagában nagyon felületes és nehezen értelmezhető elvárás. Az Apache prefork/worker modulja kb 25 évvel ezelőtti szemléletet követ (nagyon pongyolán: teljesen szinkron kliens kezelés, külön process vagy külön thread / connection).
Apache2 mellett az irány mindenképpen az mpm_event modul lesz. Ez valahol a worker modul és egy modern, teljesen aszinkron webszerver között van félúton.
Ez utóbbi már használ select/kqueue/epoll -t (megfelelőt a megfelelő rendszeren), de csak a connection kezelés async, a request-ek feldolgozása és kiszolgálása nem. Ez gyakorlatban abban fog segíteni, hogy nem lesz 5000 thread/process, illetve keep-alive mellett sem fejeli le a medence alját az Apache :)
Szóval a "cél 5-6000 egyidejű kérés kiszolgálása" értelmezésétől függően ez lehet egy röhögve megoldja vs. egy modernebb webszerver mellett is vértizzadós dolog :) Ha a kérdés felmerült, akkor mindenképp az utóbbi :)
// Happy debugging, suckers
#define true (rand() > 10)
Tehát akkor ha jól értem mivel a connection kezelés async akkor ha proxyként üzemeltetem - tényleges request feldolgozás nélkül - akkor röhögve bírnia kell?
függően, hogy mi van a túloldalon :) Konkrétumok, mérések és pontos adatok nélkül ennek a beszélgetésnek érdemben valahol itt van vége, bármi más csak találgatás és tippelgetés
// Happy debugging, suckers
#define true (rand() > 10)
A kérdésem arra irányult, hogy egy proxyként használt apache - egy szerver - ami csak átfolyatja magán az adatot mert a tényleges statikus fájl kiszolgálást - 500k-s fájl - a mögötte lévő node-ok végzik, elbírhat-e 5000 párhuzamos kérést event workerrel feltéve, hogy a mögötte lévő node-ok bírják a terhelést?
Igazából tényleg arra lettem volna csak kíváncsi, hogy van-e olyan apache a környéketeken ami nagyságrendileg hasonló vagy nagyobb terheléssel üzemel és ha igen, milyen os meg apache beállításokra érdemes odafigyelni.
van, még nagyobb terheléssel is (ha az előbbi értelmezését nézem a dolognak), de ez nem mérvadó az esetedben
// Happy debugging, suckers
#define true (rand() > 10)
arra ugyelj, ha a benchmarkot rosszul hasznalod, vonhatsz le belole hibas kovetkeztetest. pl. nem csak a szervert meri, hanem a klienst is ahonnan inditod a kereseket.
nincs valami distributed apachebench szolgaltatas, ahol ossze lehet hasonlitani a szerveredet pl. a google.com-al?
neked aztan fura humorod van...
Nagy plusz 1.
A kérdés feltevésből látszik, hogy már a tesztelés módja és a mérés elemzése korlátozza a megoldást.
Az 5k lehet viccesen kicsi, de elérhetetlenül nagy érték is, a pontos mérési profil és a környezeti egyéb elemek képességeinek függvényében. Lásd pl. ha van állapot tartó hálózat elemző eszköz (ids/ips, waf, ddos), az is simán szivathat, mert neki ugyanúgy kel felfutási idő, különben belassul, ami azt eredményezi, hogy az apache-on tovább maradnak foglalva a kiszolgáló szálak, és vagy a korlátba vagy a memóriába akadsz fel
Igen, a benchmark kliens oldalát is nézni kell, sőt lehet, hogy az a nehezebb ügy: úgy tudom, hogy a TLS kliens oldala a számításigényesebb, ami segít a DDOS elleni harban, viszont benchmarkoláskor a kliens oldalon túlerőben kell hogy legyen a számítási kapacitás a szerverhez képest!
Mennyi idő alatt kell ezeket kiszolgálni? Csak kapcsolatot kell tudni ennyit fenntartani, vagy másodpercenként ennyit ki is szolgálni? Az előbbi csak paraméterezés kérdése, nem tétel, az utóbbi esetében az 500kB példa fájl már hálózatilag is izzasztó
Kb 10 éve kellett egy képfeltöltő oldalt üzemeltetnem. Apache 6000 request/sec környéként tört le performanciában. NGINX cache szerver módban 12-14000 request/sec környéként állt meg. Ott már szerintem a hw vagy net sávszélesség volt a szűk.
Azóta 2.4-es apache lett, amit később teszteltem és jobb performanciát adott, mint a korábbi 2.2-es. Szóval amit írsz, reális elvárás.
Köszi szépen! Alapvetően ilyen válaszra vártam. Közben kiderült, hogy hálózati gebasz biztosan van, mert azonos hálózatban lévő gépről 10000 szálon headless JMeterrel hiba nélkül lefutott a teszt.
Ilyen nagyságrendeknél már érdemes a tesztet is validálni.
Tényleg megvolt a 10k (kvázi) párhuzamos thread és request?
Gábriel Ákos
Évekkel ezelőtt csináltunk egy 1M "egyszerre" login-t egy webshopra.
A tesztrendszert se volt egyszerű összelapátolni, valami 20db 16 magos gépet vettünk AWS-ben ha jól emlékszem és különböző régiókból is kellett mert megették a sávszélt. Ja és volt 10 perc ramp-up time, annyi threadet nem lehet pikkpakk létrehozni.
Asszem 5-6ezer EUR-ba került az a "tesztnap", igazából csak pár órára futott az infra de bitang nagy volt.
Gábriel Ákos
Igen, abszolút igazad van! Persze függ a teszt bonyolultságától is. Nálunk szög egyszerű most, két sima kérés, ez nem eszik sok erőforrást teszt oldalon.
Szerintem nem jól látod: 5-6000 threadet egyszerre indítani nem kicsi erőforrásigény.
Gábriel Ákos
Ez egy elég fura kérdés. Annyit szolgál ki, amennyit a sávszél, meg a hardvererőforrások engednek. Ez épp olyan, mintha azt kérdezném, hogy az asztali rendszerem hány alkalmazás vagy hány böngészőfül után térdel le, mikor azt senki nem tudja, hogy mik a hardver aktuális specifikációi, proci, mennyi RAM, miket futtatok mellette, stb.. Ezt neked kell kitapasztalni, hogy mennyi az az annyi, ha nem szolgál ki a mostani vas vagy sávszél, akkor upgrade-elsz, bővítesz. Ennek ellenére nginx-szel lehet jobban járnál, kitolnád egy kicsit a letérdelési limitet, bár ez is csak tüneti kezelés.
“The world runs on Excel spreadsheets.” (Dylan Beattie)
Ezek szerint més sose foglalkoztál komolyabban szoftver tuninggal / optimalizációval.
Gábriel Ákos
btw, ha az apache végül kiesik a képből és mást keresel, illetve az adott kiszolgáló valóban csak proxy lesz mindenféle kiszolgálás nélkül, akkor én mindenképpen a haproxy irányába fordulnék, főleg a kiegészítő szolgáltatásai miatt
// Happy debugging, suckers
#define true (rand() > 10)
Haproxy +1 ha csak proxy.
A c10K probléma amúgy réges régen meghaladott. Manapság a C1M, C10M és a C1B :) problémák vannak előtérben.
Amúgy haproxy egy darab 64 magos AWS instanceon:
https://www.haproxy.com/blog/haproxy-forwards-over-2-million-http-reque…
És a monitoring a webszerver gépen mit mutat? Bármi limitet sikerült kifektetni? Vaktában ez így majdhogynem lehetetlen feladat.
prometheus nod-exporter, apache-exporter + grafana pár perc alatt megvan és már el tudsz indulni.
Egy Flame graph meg hasznos lehet, illetve megnezni par eloadast Brendan Gregg-tol
src: https://github.com/brendangregg/FlameGraph
Egy időben üzemeltettem apache 2.4-et Centos 7-es szerveren.
Sajnos a hardverre nem nagyon emlékszem. (Intel xeon 2010-es évek közepéből és 64Gb memória)
Voltak olyan peak-ek ahol 2-3 ezer request / másodperc körül kellet kiszolgálni.
Amivel sokat "húztunk".
Felesleges apache modulok kikapcsolása. Nem is gondolnád de az rpm-es verzíó rengeteget betölt alapértelmezetten. mod_php-n volt a hangsúly.
mpm_prefork tuningja (ezzel nagyon jól el lehet játszani)
Ha ez a kerdes felmerult, akkor egyertelmuen valtani kell. Hogy mire, azt nemi performance review-k olvasasa utan tudod eldonteni, amelyik legjobban passzol a helyzetedhez (proxy/static file/...).
https://www.phoronix.com/review/amd-ryzen-7-9800x3d-linux/5
itt sajnos csak 500 es 1000 konkurens kerest teszteltek, hatha tudod hasznalni valamire.
neked aztan fura humorod van...
Nosztalgikus lesz ez a poszt. :)
Régen (20 éve :)) mindenféle sysctl net, file, vm paraméterek felhúzása/tuningolása elég jelentős teljesítmény/áteresztő-képesség növekedést tudott elérni (kernel tuning). Ha jól látom valamennyire össze van gyűjtve egy tudás a tuned projektben. Én mazsolázgatnék abból vagy állítanék egy profilt ha van a disztriben: https://github.com/redhat-performance/tuned/tree/master/profiles
Meg ahogy írták fent, az aszinkron módon működő workert (event) kellene/érdemes használni. Régen bizonyos esetekben sajátot is kellett fordítani apacsból, mert be volt égetve valami limit.
Gondolom ezen túl vagytok: https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
Ha jól emlékszem a fájlrendszer mount opciókat is szoktuk variálni (noatime, ro, ?) ott ahol a kiszolgált fájlok tárolása volt, de ezeknek a relevanciája ma már nem tudom hogy mennyi lehet.
Köszi! Ezeket megnézem.
Csak egy szerver lehet? A processnek mindenkeppen filerendszerrol kell olvasnia es kiszolgalnia? Lokalisrol? Vagy lehet cache-elt blob?
Igen, az volt a feladat, hogy az egy meglévő szervert hangoljuk.
mondjuk engem aggasztana ha egyetlen szerverrel kellene kiszolgalnom ilyen merteku rendszert aminek ilyen kovetelmenye van, mert egyszer csak tonkremegy es akkor nulla lesz a kiszolgalas, illetve akkor is, amikor frissiteni kell az OS-t, szerver alkaplmazast, webapp-ot, akarmit. De ha az ugyfelnek ez az igenye ki mondhatja el neki hogy ez igy rossz :D
Köszönöm mindenkinek a hozzászólásokat! Végül a kisebb ellenállás irányába mentünk és lecseréltük nginx-re. Így 5000 kérést simán hozott különösebb tekergetés nélkül, ennyi pedig egyelőre elégnek bizonyult.