jAbLoK

Jak se zbavit HTTP sessions

Zasláno do Scalability by Pavel Kolesnikov na Květen 26th, 2008

V příspěvcích o eBay a AppEngine jsem zmiňoval, že používání HTTP sessions nejde úplně dobře dohromady s požadavky na horizontální škálovatelnost.

Používat sessions je lákavé, umožňují programátora odstínit od bezstavovosti HTTP protokolu. Na druhou stranu, jakmile aplikace přeroste možnosti jednoho stroje, tak začnou komplikovat život, když chcete provozovat load balancing přes cluster aplikačních serverů: duplikovat je napříč servery je patrný overhead, sticky sessions neméně zjevně snižují efektivitu load balanceru.

Jinými slovy: odstiňovat programátory od bezstavovosti HTTP vlastně nemusí být až tak dobrý nápad.

Nejmenší zlo je nakonec sessions ukládat do nějakého relativně persistentního úložiště vně aplikačního serveru - zpoždění sítě a potřebné serializace a deserializace sice mírně brzdí, ale aspoň neovlivňují zbytek clusteru.

Tedy, nejmenší zlo za předpokladu, že sessions používáme.

K čemu vůbec sessions?

K čemu se vlastně HTTP sessions používají? Napadá mě:

  • udržování identity uživatele + kešování osobních dat
  • udržování stavu uživatelského rozhraní (JSF, dívám se vaším směrem…)
  • nákupní košík
  • kešování informací potřebných pro stránkování dat (opravdu to někdo radí)
  • a další - příklady uvítám v komentářích

Pokud mne laskaví čtenáři v komentářích nedoplní něčím nečekaným, dalo by se používání sessions rozdělit do následujících částečně se překrývajících kategorií:

  • autentifikace
  • kešování
  • antipatterny

Antipatterny

Nevýhody používání sessions pro ukládání aktuální pozice při stránkování dat pitvali už před necelými deseti lety členové Usenetové skupiny cz.net.internet (a po nich i před nimi jistě spousta dalších).

Z nějakých záhadných důvodů se jako typický důvod pro sessions uvádí nákupní košík. K tomu mě nenapadá jiný důvod než že jej kdysi kdosi použil v nějakém tutorialu na sessions a od té doby to každý papouškuje: košík by měl být odolný proti výpadku aplikačního serveru, navíc se neaktualizuje ani nezobrazuje tak často, aby musel být nutně kešován - zkrátka i když jeho trvání obvykle nebývá dlouhé, je velmi záhodne jej ukládat do databáze.

Jako antipattern mi osobně přijde i přístup JSF - a to ať už se stav stromu komponent ukládá do session nebo na klientovi. Ale vzhledem k popularitě tohoto frameworku mi asi něco uniká. Doufám.

Kešování

Session může působit dojmem jako bezva struktura pro kešování, aspoň dokud si člověk neuvědomí nevýhody popsané více. A dokud nezačne kešovat data, která mohou být modifikovány v rámci jiných sessions. A když si nevýhody uvědomí, tak nejspíš sáhne po něčem, co bylo pro kešování navrženo a uvedenými nedostatky ve škálovatelnosti netrpí. Třeba memcached. A těch pár zlomků sekundy na zpoždění sítě a (de)serializaci holt obětuje.

Autentifikace

Session se asi nejčastěji používá pro udržování informací o přihlášeném uživateli. Fakticky se ale jedná o speciální případ kešování popsaného níže - pokud víme, že o uživateli potřebujeme znát skutečné jméno, adresu, a základní preference, prostě si je můžeme nasypat do memcached pod těžkouhodnutelným klíčem generovaným podobným mechanismem jako session.

A pokud od autentifikace očekáváme jen ověření identity uživatele, můžeme prostě do cookie nastavit přímo identifikátor uživatele, jen digitálně podepsaný nebo ještě lépe zašifrovaný. Pokud autentifikační služba není izolována na vlastním clusteru, symetrické šifrování by mělo bohatě postačí. Na druhou stranu se v tomto případě se musíme postarat o pár praktických záležitostí okolo správy klíčů a deploymentu.

Obrázek: Možnosti ověření a interpretace authentication tokenu - kešování a kryptografie

Kryptohrátky jsou zbytečným overheadem v tradični aplikaci, kdy většina požadavků je zasílána za účelem vykreslení celé stránky - typicky vždy budete muset znovu zobrazit jméno uživatele a podobně, tudíž si hrábnutí do cache neušetříte.

Naopak pokud si mantru “udržovat stavu na klientovi” vykládáte po vzoru GMailu tak, že webová aplikace se sestává z pár HTML stránek, kterou uživatel porůznu aktualizuje AJAXem, pak samozřejmě může kryptografické ověřování a interpretace session tokenu přispět ještě o trošku k lepší odezvě a škálovatelnosti.

Pokud někomu ze čtenářů zbudou síly něco napsat, zajímalo by mě:

  • k čemu výše neuvedenému používáte sessions?
  • zkoušeli jste v praxi vytvořit bez použití sessions netriviální víceuživatelskou webovou aplikaci?
  • a pro znalce a fanoušky Java Server Faces - máte po přečtení výše uvedeného dojem, že mi ohledně této technologie něco zásadního uniká? :)

Odkazy

eBay, Java a škálovatelnost

Zasláno do Java, Scalability by Pavel Kolesnikov na Duben 28th, 2008

Jak to vypadá, když se za pomocí J2EE vytváří webová aplikace, jejíž databáze obsahuje přes dva petabajty dat (peta = 10245) a jejíž dvě stě milionů registrovaných uživatelů jejím prostřednictvím v kterýkoli čas nabízí okolo sta miliónů položek?

Architektura eBay

  • na nejhrubší úrovni rozděleno na databázovou vrstvu, aplikační vstvu, vyhledávací systém a operations
  • Aplikační vrstva:
    • nedrží stav (tedy žádné sessions, natož stateful session beans)
      • schválně jsem se podíval na HTTP hlavičky, zaujala mě cookie jménem “nonsession” ;)
    • asi 100 funkčních celků, v terminologii eBay “apps” (někdo by možná řekl “business services”), dohromady to dělá cca 15,000 serverů
    • aplikační servery spolu nekomunikují, běží nezávisle na sobě (což lze snadno díky předchozímu bodu)
  • Databázová vrstva:
    • rozdělena vertikálně na něco přes 70 funkčních celků (databází). Ty jsou dále řezány horizontálně podle hlavního klíče pro daný logický celek
    • většina náročných obvykle databázových operací se provádí na aplikační vrstvě; zmiňují se joiny, kontrola referenční integrity, třídění. Nepěstují se žádné uložené procedury (sem tam nějaký jednoduchý trigger)
    • eBay nepoužívá transakce (tedy kromě PayPalu, který pod eBay taky patří)
    • v praxi to znamená, že je vymezena skupina životně důležitých dat, které musí být vždy v konzistentním stavu, u ostatních se garantuje pouze “best effort”

Kdy se hodí Java?

Zajímavé jsou použité technologie: J2EE (konkrétně WebSphere) a Oracle, čímž se eBay výraně odlišuje od různých Flickrů a podobné havěti. Co mají ale tyto weby s eBay společné, jsou architektonické patterny, které se na hony vzdalují představě správné J2EE aplikace z dob EJB2.0. Ale na tom samozřejmě není nic divného.

Proč tedy v eBay Javu vůbec používají?

Dan Pritchett ve své prezentaci z roku 2006 píše: “[we] rewrote the entire application in J2EE … which gave us chance to architect the code for reuse and separation of duties”. A co si tak vzpomínám, to byl možná hlavní důvod, proč jsem se kdysi dávno po nějakých pěti letech s Perlem a PHP pouštěl do psaní webových aplikací v Javě.

Odkazy

Tagged with: , , ,

Databáze a škálovatelnost

Zasláno do Uncategorized by Pavel Kolesnikov na Duben 21st, 2008

Prosba pro čtenáře Jabloku: pokud vás nadpis odradil, dejte šanci aspoň poslednímu odstavci. Díky.

V původní zmínce o Google AppEngine na Jabloku jsem se zmínil, že při tvorbě vysoce škálující aplikace se vývojáři (vlastně i architekti) musí nemálo omezit. Aspoň pokud si škálovatelnost nezaměňují s “bude to nějak fungovat i na WebLogicovém clusteru”

Podobně i poznámky z mailing listu o GAP zesumarizované na HighScalability.com se dají shrnout následovně:

  • i ve velmi zatížené databázi jdou některé databázové poučky stranou
  • v distribuované databázi tím tuplem

Pokud předpokládáme, že tam někde vzadu dříme neomezeně výkonná databáze, tak napsat škálující aplikaci je celkem triviální. Takový předpoklad je ale příliš silný. Když se podívám kolem sebe, nejpopulárnější jsou následující typy řešení:

  1. Postavené na marketingu: vezmeme drahý hardware, velké diskové pole, rozběhneme drahou automagii typu Oracle RAC (wiki) a budeme doufat, že to našim potřebám postačí.
  2. Postavené na skromnosti: vezmeme levný hardware, memcached nebo nějaké podobné kešovátko, a budeme doufat, že to našim potřebám postačí
  3. Postavené na ambicích: stanovíme si neomezeně škálující databázi jako hlavní zadání a vypadne nám S3 nebo BigTable. Sami to asi dohromady nedáme, ale můžeme či budeme moci si za rozumný peníz pronajmout cizí infrastrukturu.
  4. Postavené na koleně: zamyslíme se nad tím, co naše aplikace chce a jaká omezení jsou akceptovatelná, a zohledníme požadavky na škálovatelnost databáze už v návrhu aplikace. Vypadne nám třeba něco jako Flickr.

Varianta č. 1 se úspěšně etablovala v oblasti interních podnikových aplikací - požadavky na škálovatelnost jsou relativně omezeny velikostí korporátu, a utrácení peněz za hardware a licence u velkých dodavatelů je přece osvědčený postup ;)

Druhá varianta je úspornější variantou téhož, i když zlí jazykové mohou poukázat na to, že úspora za hardware a licencích se vykompenzuje náklady na lidi. Těžko říct.

Varianta třetí je nejmladší. Škálovatelnost obvykle znamená, že databáze je při jakémkoli zatížení a objemu dat stejně, byť jakž takž únosně pomalá. Nutno kombinovat s variantou č. 2 (kešování). Omezení jsou předem daná - mohou vás odradit, na druhou stranu vás ochrání před tím, abyste si je bolestivě objevovali sami.

Varianta poslední byla obvykle implementována jako znouzectnost firmami, kterým předchozí varianty nestačily (a často v době, kdy varianta č. 3 nebyla na trhu). Pokud se člověk poučí od ostatních, může to být pro složitější aplikace zlatá střední cesta.

Názory ctěného čtenářstva uvítám. Pokud váš názor je “jdi s tím do háje, na jabloku chci číst o Javě”, dejte prosím taky vědět. Díky.

Tagged with: ,

Škáluj jako Google

Zasláno do Uncategorized by Pavel Kolesnikov na Duben 11th, 2008

Předevčírem jsem se o své první dojmy z EC2 chtěl nadšeně podělit s Františkem. Jenže František je - jak známo - všude první, a tudíž mohl být nad nějakou virtualizaci povznesen - samozřejmě už předtím četl spekulace o tom, že se Google chystá nabídnout svou infrastrukturu jako službu. Což se během dvou dnů také stalo.

Služba se jmenuje appspot.com, a v tuto chvíli se nachází ve stadiu “preview release”, což znamená testovací provoz pro prvních 10,000 zájemců, kteří se ozvali během několika hodin po oficiálním oznámení (já to bohužel nestihl). K dispozici je vývojové prostředí AppEngine, které obsahuje potřebné knihovny a hlavně lokálně spustitelný runtime, v němž je možná aplikaci otestovat před uploadem na appspot bez jakýchkoli úprav. Služba je při omezené návštěvnosti a velikosti persistentních dat zdarma, v plánu je placená varianta, kde tato omezení padnou.

AppEngine nabízí oproti Amazonu škálovatelnost transparentní, samozřejmě za cenu jistých omezení. Zatimco amazoními služby (AWS) vám usnadňují žonglování se serverovou farmou, jejíž možnosti můžete využívat dle architektonické i programátorské fantazie, Google vás zcela odstiňuje od konkrétního (byť virtuálního) serveru, operačního systému a jeho limitů. Zkrátka poskytuje transparentně škálující aplikační server.

Tato transparentnost je samozřejmě možná jen za cenu několika omezení, které musí takto vyvíjená a nasazená aplikace splňovat. Namátkou:

  • Persistentní vrstva
    • Používá speciální API a dotazovací jazyk pro persistentní ukládání dat (pro lepší srozumitelnost ale budu dál používat pojmy z relačnch databází)
    • Omezené dotazovací možnosti (nelze “najít NULL”, nelze kombinovat porovnávací operace nad více “sloupci” a pokud je použijeme, musíme je v připadné ORDER BY klausuli dát na začátek, a navíc není podporován operátor nerovnosti)
  • Aplikace běží v omezeném kontejneru (sandboxu), který neumožňuje:
    • zápis na filesystem; číst je mоžné pouze soubory aplikace
    • práci se sockety (je ale možno použít explicitně poskytovanou službu pro odesílání e-mailů a pro přístup k vzdáleným zdrojům přes HTTP či HTTPS přes standardní porty)
    • spouštět nová vlákna nebo procesy
    • zpracovávat požadavek příliš dlouho
    • další systémová volání (např. práci se signály)
  • Veškerá serverová logika se točí okolo zpracovávání požadavků, žádné další služby jako plánování úloh nejsou k dispozici
  • Jediný podporovaný jazyk je (zatím?) Python

Jestli jste se někdy zajímali o to, jak škálují weby jako Flickr, Wikipedia, Amazon nebo samotný Google, asi je jasné, že dobře škálující aplikace prostě musí být s ohledem na škálovatelnost navržena. Jinými slovy, musí brát v úvahu některá omezení: nepřehánět to s normalizaci dat, s používáním sessions, nenačítat při zpracování požadavku zbytečně mnoho dat, snažit se o co nejrychlejší odezvu atd. atd. Z tohoto pohledu jsou omezení AppEngine pochopitelná - nějak byste se omezit stejně museli, takže Google vám vlastně jen nutí své best practices.

Škálovatelností se samozřejmě nedá vysvětlit omezení na Python - ale darovanému koni na zuby nehleď. Předpokládám, že spolu s placenou verzí budou další jazyky muset následovat. Na druhou stranu si dokážu představit, že při určitém poměru návštěvnosti a složitosti aplikace by hodnota infrastruktury mohla převážit jednorázové náklady na nahrazení aplikace i programátorů pythonovými alternativami ;)

Zdroje:

Tagged with: ,

Škáluj jako Amazon

Zasláno do Uncategorized by Pavel Kolesnikov na Duben 9th, 2008

Předevčírem večer jsem - uznávám, že s mírným zpožděním - objevil Amazon Elastic Cloud (neboli EC2, toho času v beta-verzi). EC2 díky virtualizaci nabízí ekvivalent dedikovaných serverů, které si můžete přidávat či ubírat dle libosti. Je vaše aplikace v noci bez návštěv a odpoledné nestíhá odpovídat? Prostě si ráno zapnete další server a v poledne třeba ještě další dva, a na noc naopak necháte jen jeden.

Virtualizace jako služba zákazníka odstíní od otravných záležitostí souvisejících s hostováním webové apliakce. Stačí si připravit image operačního systému s předinstalovanou vlastní aplikací, a vše ostatní už se zařídí přes Amazoní API. Případně přes balík nástrojů Cloudtools od Chrise Richardsona.

Výhodou není jen flexibilní správa serverové infrastruktury: s EC2 máte především pod kontrolou průběžné náklady. U Amazonu platíte od hodiny a serveru, a k tomu pár šušňů za přenos dat. Ceny jsou velmi kulantní: hodina provozu instance s 7.5 GB RAM a ekvivalentem dvou Xeonů na 1.7 GHz a blíže nespecifikovanou “high” I/O performance vyjde na 40 centů, tedy momentálně něco přes 4,500 Kč měsíčně. Skromnější jednoprocesorová verze s 1.7 GB RAM vyjde na čtvrtinu. 18 centů za gigabajt odchozích dat měsíčně (tedy 284 kč za 100 GB!) se pak v nákladech víceméně ztratí.

Z toho plyne, že pokud vaše aplikace není napsána příliš distribuovatelně, klidně si můžete podle denní doby přepínat mezi dělem a šunkou, chce to jen dvakrát denně před přehozením výhybky přesypat změněná data. Jedním slovem, radost.

Mimochodem, nedávno v konferenci o SEO Dušan Janovský vysvětloval ekonomická omezení objemu dat indexovaných Seznamím vyhledávačem; ve stručnosti: máte servery, ty něco stojí, něco žerou, navíc oproti globálně působícímu Googlu nejde dobře rozkládat špičku. Nabízí se otázka: nechce Seznam vlastní serverovnu zabalit a přejít k Amazonu? :-)

Tagged with: , , ,