Nagy terhelésű rendszerek fejlesztése 1. – Alkalmazás-evolúció
Előbb-utóbb minden sikeres internetes vállalkozás eljut arra a pontra, hogy egy gép már nem bírja el a terhelést, és el kell gondolkozni azon, hogyan is osszuk azt el. Ez nem pusztán a rendszergazda feladata, sokszor el kell gondolkozni az ilyen környezetben futtatandó szoftver alkalmasságán is.
KISS – Az egyszerűbb jobb
A sorozatban megjelent
- Nagy terhelésű rendszerek fejlesztése 1. – Alkalmazás-evolúció
- Nagy terhelésű rendszerek fejlesztése 2.
- Nagy terhelésű rendszerek fejlesztése 3.
- Nagy terhelésű rendszerek fejlesztése 4. – Üzemeltetés
A talán leggyakrabban elkövetett hiba amikor az ember kinövi az egy szem gépét, hogy megpróbálja a feladatot internetről összeszedett technológiákkal megoldani. Ezek a technológiák ugyan működnek, de rejtenek olyan buktatókat, amik a szolgáltatás minőségének romlásához vezetnek.
Javaslatom tehát azoknak, akik kinőtték a gépüket, hogy próbálják meg először a meglevő szolgáltatásokat szétszedni, áttenni például az adatbázisszervert egy másik gépre, mielőtt valamilyen cluster technológiához nyúlnak. A cluster technológiák önmaguk is egy bonyolultságnövelő tényező, még egy dolog, ami elromolhat, és jókora tapasztalat nélkül csak csökkentik a rendelkezésre állást, mintsem hogy növelnék.
Tehát: éles környezetben kerüljük az ismeretlen technológiákat, és próbáljunk meg alkalmazások szintjén terhelést bontani.
Az optimalizálás sorrendje
Bár az alapszabály úgy szól, hogy a fejlesztő ideje drágább, mint még egy gép, adott esetben érdemes rászánni néhány munkaórát arra, hogy gördülékenyebben fusson a rendszer. Fontos szempont az optimalizálásnál, hogy föntről lefele haladjon az ember. Fölösleges ugyanis egyből az egész rendszermag átírásába kezdeni, ha tizedannyi energiával sokkal jelentősebb sebességnövekedést lehet elérni a kliens oldal optimalizálásával.
Ha mégis elérkezik az a pillanat, hogy a rendszer magjában van valami, ami a terhelést okozza, nagyon lényeges, hogy ne kezdjen el vaktában optimalizálni senki. Lehet, hogy egy algoritmus nem hatékony, de ha óránként csak egyszer fut le, nem ő a ludas a terhelésben. Egy rossz UI döntés ezzel szemben egészen könnyedén okozhatja a gép beborulását.
Egy pár éve az akkori munkahelyemen a kollégák fejlesztettek egy Flash játékot, és ez a játék nagyon megviselte a szervert. Mivel igen komoly tétje volt a játéknak, a felhasználók egy rontott pályánál azonnal kiléptek, és újból kezdték a játékot. Ez azzal járt, hogy a játék lekérte a szerverről a toplistát. Abban a pillanatban, hogy bekerült a játékba a pálya újrakezdését lehetővé tevő gomb, a szerveren a terhelés töredékére esett vissza.
Tehát: rendszerezetten optimalizáljunk, mérjünk, mielőtt elkezdünk kódolni.
Memóriából kiszolgálni
Biztos mindenki mérgelődött már azon, hogy mennyit „reszeli a diszket” a gép, majd egy memóriabővítés után rácsodálkozott arra, hogy az elvileg semmilyen sebességnövekedéssel nem járó művelet után mennyivel gyorsabb lett. Memóriából kiszolgálni a létező leggyorsabb dolog. Szerencsés esetben memóriából kiszolgálva egy gép akár egy gigabites hálózati interface-t is ki tud hajtani 80-90%-ig.
Ha nem teszünk semmit, akkor is jótékony hatással van a kiszolgálás sebességére a sok üres memória, ugyanis az operációs rendszer a rendelkezésre álló üres memóriába betölti az éppen használt fájlokat. Ez az úgy nevezett file cache.
10 GB file cache egy webkiszolgálón
Az ennél hatékonyabb megoldás úgy működik, hogy az alkalmazás részeit tesszük memóriába. Erre változatos technológiák léteznek (amiket a fent említett játékos példánál is lehetett vona használni, ha akkor rendelkezésre állt volna). A talán legismertebb a NoSQL mozgalom egyik előhírnöke, a memcached. Ha az alkalmazás felkészült arra, hogy bizonyos objektumokat pl. a DAO rétegből memcachedben tároljon, az adatbázishoz hozzá sem kell nyúlni. De hogy ne csak adattárolásról beszéljünk, ha az üzleti logika megengedi, akár az egész nyitólapot, vagy egy bonyolult lekérdezés eredményét (pl. top 10 valami) be lehet tárolni memcachedbe, és csak néhány percenként kell újragenerálni.
Figyelem! Ugyan mostanában divatos NoSQL-ben gondolkozni, érdemes figyelembe venni, hogy egy-két gépen a clusterelt üzemeltetésre kihegyezett szoftverek, mint pl. az Apache Cassandra rosszabb eredményeket fognak produkálni mint az SQL adatbázis! Természetesen ugyanez igaz az elosztott fájlelérést biztosító cluster fájlrendszerekre is.
Tehát: legyen elég szabad memória a filecache-nek, használjunk memória tárolókat.
Háttérfolyamatok futtatása
Sokszor, főként böngészős játékok írásánál, előkerül az a kérdés, hogy hogyan is kell(ene) a kvázi valós idejű vagy háttérben futtatandó feladatokat megvalósítani. Ilyenkor aztán előkerülnek az olyan meredekebbnél meredekebb ötletek, mint például a screenben futtatás vagy a crontabból való indítás. Erre a korrekt és technológiailag védhető megoldás egy úgynevezett daemon írása. A daemon egy olyan alkalmazás, ami lekapcsolódik az őt indító terminálról, és a háttérben fut tovább.
Egy daemont írni nem különösebben nehéz, pusztán néhány alapvető operációsrendszer-közeli dologgal kell megismerkedni. Ebben nagyon nagy segítséget tud nyújtani egy rendszergazda, aki ismeri ezeket a követelményeket, de egy operációs rendszerekről szóló könyv vagy egyetemi jegyzet is csodákra képes. Ha a közelben van egy rendszergazda, akkor érdemes kifaggatni a daemon írását megkönnyítendő azokról az eszközökről, amiket az operációs rendszer egyébként is nyújt (pl. start-stop-daemon).
A daemonoknak van több előnye is, nézzünk egy konkrét példát. Feladat egy olyan daemon írása, ami bármikor ébreszthető, ellenben amikor nem csinál semmit, akkor nem eszik CPU-t. Egyszerű megvalósításként elindítjuk a daemont, ami az ő process ID-ját (PID) leteszi valahova, ahol megtalálja az alkalmazás, majd elteszi magát aludni (sleep). Ha a webes frontend szeretne tőle valamit, elolvassa a PID-et, és küld neki egy SIG_INT
-et, aminek hatására a sleep meg fog szakadni, a daemon előre beállított signal handlere pedig lefut, értesülve arról, hogy feladat van.
A fenti feladat még PHP-ban is megvalósítható (pcntl és posix library), bonyolultabb feladatokhoz azonban érdemes körülnézni a Python vagy Perl nyelvekben egy kicsit. Természetesen a téma annál azért bonyolultabb, mintsem hogy egy egyszerű scriptből daemont vagy cron scriptet csináljunk. Ügyelni kell adott esetben arra, hogy ne futhasson több példány egyszerre, a rendszerleállításkor konzisztens maradjon az állapot stb. Ezen problémák ecsetelése azonban egy önálló cikket is kimerítene.
Tehát: attól, hogy van egy kalapácsunk, nem minden szög. Ne szégyeljünk a rendszergazdától kérdezni, és operációs rendszereket vagy új programnyelveket tanulni.
Kérdezzünk a rendszergazdától
Általánosan elterjedt tévhit, hogy a fejlesztők lefejlesztik az alkalmazást, a rendszergazdának pedig az a dolga, hogy megteremtse a működéshez szükséges feltételeket. (És nem azért mert rendszergazda vagyok.)
A projekt sikeressége érdekében érdemes a rendszergazdát bevonni a csapatmunkába. Mivel a fő feladata az, hogy minél több szoftvert és technológiát ismerjen, gyakran olyan megoldásokkal szolgálhat, amik egészen egyszerűvé vagy éppen szükségtelenné tesznek egyébként bonyolult feladatokat. A másik oldalról meg olyan a határidőre káros problémáktól óvhat meg egy nagy terhelésű rendszer fejlesztésénél, amikbe fejlesztőként szinte kötelezően belefutnánk.
Tehát: a rendszergazda mély rendszerismerettel rendelkezik, ezt használjuk ki!
Folytatjuk…
Ez a cikk megpróbált rávilágítani azokra a sarokpontokra, amikbe szinte mindenki belefut. Természetesen a téma ennél bővebb, ezért a sorozat következő részeiben azokkal a technológiákkal és problémakörökkel foglalkozunk, amik a tényleges elosztott működéshez szükségesek.
Köszönöm Tyrael és Kayapo segítségét a cikk összeállításában.
■
nadon jó
Bár ért a szerverekhez az ember, meg néhány programnyelvhez de azért mégsem olyan, mint aki a nap24 óráját a gépházban tölti.
Köszi!
Rendkívül hasznosnak ítélem amit csinálsz!
Köszönöm
Redis
Redis
Attól függ, hogy milyen adatod van. A key-value store-ok általában ott jók, ha nem relációkkal terhes az adatszerkezeted. Ha SQL-ben is csak 6-7 joinnal tudnád leképezni az adataidat, jók az esélyek arra, hogy a KV storeban a lookupolgatás megeszi az előnyeit és a lookupok leprogramozása miatt ez plusz időt valamint plusz hibalehetőségeket jelent.
Egyszóval, a KV storeok ott jók, ahol egyszerű szerkezetű viszont sok adatod van. Egy sima weboldalnál lehet, hogy nem is bajlódnék vele (lásd a túl korai optimalizálás témaköre). Sokkal inkább olyan dolgokat tennék KV storeba, amiket csak elő kell rántani, pl egy termékoldalnál a termékek kigenerált adatlapjait.
Redis
mostanaban a csapbol is a
tok jo cucc, a fejlesztoje az egyik legjobb hozzaallasu opensource fejleszto odakint, de kezdem azt erezni, hogy nagyon sokan csak a hype miatt dobaljak be mindenhova a "csinaljuk meg redissel" mondatot.
kicsit olyan, mint anno a "Imagine a Beowulf cluster of these"-
en azt javaslom, hogy a feladathoz valasszuk az eszkozt, es ha oda redis a megfelelo, akkor azt kell hasznalni, ha sqlite, akkor azt, ha oracle, akkor meg amazt.
ps: mit csinalnanak a cronjobok? elsore kicsit ad-hocnak tunik ez a felallas.
Tyrael
Grat
Várom a folytatást
Köszönjük a ráfordított időt!
nekem is nagyon tetszett,
köszi
gratula
jo lett, varom a folytatast.
Tyrael
hiánypótló
ugyanakkor ami elsőre eszembe jutott, hogy bárcsak ezt jelentené manapság mifelénk a "rendszergazda"...
kicsit az a negativ felhang ugrott be, hogy - ha neked volnék - én lassan kikérném magamnak a "rendszergazda" jelzőt, ahogy sok webre dolgozó tervezőgrafikus sem szivesen azonosul már az önjelölt "webdizájner" -ekkel, akik nagyjából gradienseket huzogatnak photoshopban ész, szem és koncepció nélkül.
node félre a szájhúzást! várjuk a további értékes tudást az avatott főktől!
Tegnap raktak ki
goal-driven-performance-optimization
Tyrael
Várjuk ...
Sziasztok! Nem akarok
Nem akarok okosabb lenni annál, amit a szerepem megkíván. Nem pontosan az az egyik lényegi pontja az Enterprise alkalmazásoknak, hogy skálázhatóak legyenek? Úgy tudjam növelni a teljesítményt, hogy az alkalmazást ne kelljen leállítani?
Ha ilyen téma érdekel bárkit is, akkor érdemes elővenni egy könyvet ami erről szól. Igen, jáváról és .NET -ről lesz bennük szó. De még az is lehet, hogy RoR is megemlítésre kerül.
Php -val nem lehet elérni enterprise szolgáltatás szintjét.
Ilyen szempontból semmi új nincsen a cikkben. Sajnos.
Nem akarok okosabb lenni
A második mondatot nem értem az első idézet kontextusában, mert lehetséges a kérdéseidben megfogalmazott követelményeknek megfelelő alkalmazást írni PHP alapokon (skálázható az alkalmazás leállítása nélkül). Ezeket a követelményeket kielégíteni csupán tervezés kérdése.
Mire gondoltál ezen túl?
Enterprise, vagy nem
Had hozzam példának én a yahoo után a Google mindenféla szolgáltatásait. Több tucat féle szolgáltatás, legalább ugyan ennyi féle megvalósítás. A repertoárban a java-tól, php-tól python-on keresztül a c-ig, c++-ig terjed a skála. Sok estben a megoldás az "egyszerű" (mindenkitől elnézést kérek) "webtákoló" programozónak óriási hülyeségnek tűnhet. (Van náhány mysql cluster -ük amiket kiselejtezett pc-k alkotják, néhány ezer!!!).
Szóval az enterprise szolgáltatás pont arról ismerszik meg, hogy indiferens, min valósítják meg, a szolgáltatott erről (jó esetben) nem is értesül, nem látszik!
Szóval ne vagdalkozzunk ilyen kijelentésekkel, hogy PHP-ban nem lehet, de javaban, meg .NET-ben meg bizony lehet nagy terhelésű rendszert megvalósítani.
Azt ne felejtsük el, hogy
Én is írtam már gSoappal szervert C++-ban, PHP appklienssel, ergo lehet szép többszintű architektúrát tervezni így is, de tényleg szebb/könnyebb Javaval, .Nettel.
Zend Framework alatt egesz jo
Halisten, most valami megmozdulni latszik, php-internals-on mar hetek ota megy az otleteles, hogy hogyan kellene megoldani a scalar tipusok hinteleset.
Tyrael
Majd lesz
Ami a konkrét technológiai megvalósításokt illeti (skálázás szempontjából is), azokról a cikksorozat további részében lesz szó.
Mégis lehet
Flickrnél, Facebooknál, Ustreamnél valahogy mégis elérik ^^.
yahoo
Á, minek.
A PHP igen jol skalazhato,
kis idezet:
The Java platform (Enterprise Edition) differs from the Java Standard Edition Platform (Java SE) in that it adds libraries which provide functionality to deploy fault-tolerant, distributed, multi-tier Java software.
Ebbol melyik osszetevo az, ami szerinted megvalosithatatlan PHP hasznalata eseten?
Plusz webszervert barmikor be tudsz rakni a load balancer/reverse proxy moge, es maris novelted a kapacitasodat.
A tobbi osszetevo (perzisztencia reteg, stb.) meg ugyanugy lehet barmi, sqlite-tol oracleig, redis-tol cassandra-ig.
Tyrael
Mi az Enterprise egyáltalán?
Jó kis cikk, jó kis sorozat lehet még belőle, csak így tovább!
Az Enterprise témakör körüli kis flame számomra egy valamit mutat jól - igazából senki sem tudja pontosan mit is jelent :) Mindenkinek mást.
Én azt a véleményt osztom, hogy az enterprise szintnek semmi köze pl. a skálázhatósághoz. Az enterprise szintű szoftver olyan összetettségű szoftvert jelent, ami meg tudja oldani egy komplett enterprise (vállalat) problémáit. Ennél fogva ide sorolható minden, a CRM-től, CMS-től kezdve az ERP-ig. A zavart az okozza, hogy az enterprise elnevezés, mint olyan az utóbbi időben egyfajta minőségi faktort is képvisel a legtöbb embernél (kinél pozitívat, kinél negatívat). Az enterprise hívőknek megbízhatóságot, supportot, magas szintű konfigurálhatóságot jelent, míg az ellentábornak bonyolultságot, komplexitást, felesleges lassúságot.
Persze egyik sem feltétlenül igaz. És a fenti gondolatmenetbe kapaszkodva azt is kimerem jelenteni, hogy önmagában valami nem a Java-tól lesz enterprise szintű, vagy sem. PHP-ban is lehet komplex, megbízható szoftvert írni, amin sok esetben nagyvállalatok mindennapi tevékenysége múlik - gondoljunk csak pl. a Sugar CRM-re.
Még egy kommentem lenne a "memóriából kiszolgálni" c. részhez. Ajánlom mindenki figyelmébe a Varnish proxy fejlesztőjének, Poul-Henning Kamp-nek a cikkét (aki mellesleg a FreeBSD egyik core fejlesztője), azaz:
Mi a gond az 1975-ös stílusú programozással? http://varnish-cache.org/wiki/ArchitectNotes
A cikkben hosszasan taglalja a konkurens proxy (Squid) példáján keresztül, hogy miközben bizonyos fejlesztők abban a tudatban trükköznek a memória használattal, hogy azt hiszik, hiper-optimalizálást hajtanak végre, azt nem tudják, hogy ezzel megkerülik az oprendszer memória menedzsmentjét, gyakorlatilag egy anti-optimalizálást végrehajtva. Azaz - ha már előjött a KISS - érdemes megérteni magát a futtató környezetet és a userland működését is, mert lehet, hogy sok esetben olyan dolgok fejlesztésével bonyolítja az ember az életét, amely problémákra már maga az oprendszer is tudhatja a választ (pl. fájlok cache-elése memóriába).
Szemely szerint azert
"pl. fájlok cache-elése memóriába"
ezt Janoszen(Proclub) is megemlitette:
"Ha nem teszünk semmit, akkor is jótékony hatással van a kiszolgálás sebességére a sok üres memória, ugyanis az operációs rendszer a rendelkezésre álló üres memóriába betölti az éppen használt fájlokat. Ez az úgy nevezett file cache."
Tyrael
What is enterprise about
A hozzászólásodat olvasva amúgy rögtön ez blogpost ugrott be.
Enterprise is not about code quality, enterprise is not about Java, enterprise is not about .NET, enterprise is not about scalability, enterprise is not about Oracle...
;)
NoSQL demistified
K-V tárolók - ahogy a cikkíró nagyon helyesen meg is jegyzi - már régóta vannak, a memcache már régi történet, más kérdés, hogy a NoSQL mozgalom erősödéséig mindössze "buta" cache-ként volt használva a relációs DB-k mellett, azok kisegítésére.
A NoSQL elgondolás szerint azonban nem feltétlenül szükséges mindent relációs alapokon tárolni (pl. az alkalmazás állapotát) - akkor pedig minek emeljük be az alkalmazásba a komplex relációs rendszereket? (Megjegyzem, C programozók aligha kezelik ezt forradalmi újdonságként, mivel a láncolt listák is léteznek már vagy 40 éve.)
"Tákololós-webes" világban azonban ez nagy újdonság, és a figyelmet ez az irányzat terelte a K-V tárolók felé. Ezekből viszont rengeteg féle-fajta van.
A Cassandra/Voldemort vonal az Amazon Dynamo whitepaper-jére épül, és lényege, hogy egy DHT (Distributed Hash Table) alapokon működő, decentralizált/elosztott rendszert valósít meg. Fontos tudni, hogy mindegyik ilyen megoldás ún. eventually consistent modellt valósít meg - magyarul egy gyenge konzisztenciát biztosító, nagy rendelkezésre állású rendszert lehet vele építeni. Ha ez a cél. (A tudomány mai állása szerint nem tudunk egyszerre nagy rendelkezésre állású, konzisztens, és a hálózati partíciókat toleráló elosztott rendszert építeni, ezekből egyszerre csak kettő valósítható meg, lásd CAP Theorem - http://pl.atyp.us/wordpress/?p=2521)
A Redis teljesen más replikációs mechanizmust használ, így véleményem szerint a felhasználási területe is más. Vannak továbbá olyan megoldások is, amik K-V alapokon kínálnak ACID-kompliens megoldásokat (Scalaris, FireGem). Jól látható, hogy ezek teljesen más célokat valósítanak meg, mint a gyenge konzisztenciát megvalósító Dynamo-vonal.
Érdemes tehát egy kicsit félretolni a hype-ot, és megérteni, hogy pontosan mit és hogyan tudnak ezek a rendszerek. Az esetleges előnyök szvsz nem abból fognak származni, hogy valaki leszúr egy Redis-t a MySQL mellé, hanem abból, hogy relációs séma helyett key-value alapú adatstruktúrát hoz létre, ezáltal teljesen más alapokon gondolkodva hozva létre az alkalmazását. Innentől fogva az alatta nyugvó technológia cserélgethető alkamazási területtől és céloktól függően.
Sok okos ember
A hozzaszolasodrol egybol ez
http://blog.couch.io/post/511008668/nosql-is-about
Tyrael
No silver bullet
Ez nagyon jó