úterý 9. října 2007

Lekce ze škálovatelnosti

V článku Teorie a praxe v J2EE světě jsem se pozastavoval nad rozdílem mezi tím, co si můžeme přečíst v chytrých knihách o J2EE a tím jaká je praxe. Praktický pohled poskytla prezentace o architektuře systému eBay. Nati Shalom otevřel související diskusi na téma Why most large-scale Web sites are not written in Java.

Nati Shalom vyšel z dat sesbíraných ze serveru HighScalability viz následující tabulka.

Tabulka ukazuje, že preferovaným stackem je LAMP (Linux, Apache, MySQL, PHP|Perl). Je více než patřičné ptát se proč. Nati správně poukazuje na patrný rozdíl mezi požadavky web aplikací a mission-critical aplikací, které jsou obvykle stavěné nad J2EE stackem. Nicméně v oblasti škálovatelnosti vidí společné oblasti pro oba typy aplikací.

  • cacheování na úrovni datové vrstvy (minimalizace diskových IO operací)
  • snaha o Horizontal partitioning
  • minimalizace distribuovaných transakcí
  • snadná paralelizaci na úrovni aplikační vrstvy

Problém J2EE je v tom, že škálovatelnost je jakýsi virtuální pojem, který se táhne specifikací a marketingovými materiály. Z praktické zkušenosti s J2EE stackem mohu říci, že řádně škálují maximálně tak servlety. Pokud tedy chcete napsat vysoce škálovatelnou aplikaci v J2EE, nezbude vám nic jiného než spoustu technologií úplně vynechat.

K dobru přikládám moje tipy na architekturu dobře škálující střední vrstvy.

  • Bezestavový design a idempotentnost operací
  • lokální transakce
  • Hibernate
  • In memory data gridy
  • Spring

Stateless nebo česky bezestavový design je první předpoklad k dobré škálovatelnosti, znaméná totiž že není potřeba synchronizace stavu přes cluster. Pro dobré fungování aplikace je potřeba brát v potaz jistou toleranci k chybovosti, to by měla zaručit idempotentnost operací (výsledek operace se nemění v závislosti na počtu volání). Lokální transakce, protože JTA nepřináší žádné výhody v případě jediného transakčního participanta, naopak přidává zbytečnou režií.

Hibernate protože má podporu pro transakční cache (first level cache), velice snadno lze nakonfigurovat vysoce výkonnou second level cache (Comparing Memcached and Ehcache Performance díky Kolesi!), navíc by měl umožnit i horizontal partitioning. In memory data grid pokud již potřebujete držet nějaký stav, protože prostě řešení určená pouze a jenom pro škálování fungují lépe, než podpora v aplikačních serverech. A konečně Spring, kterým to všechno spojíte bezbolestně dohromady.

Závěrem, i v J2EE jde napsat aplikace, která bude dobře škálovat jenom musí člověk vědět jak na to...