A HTML 5 és CSS 3 újdonságai

Beindult a marketing gépezet a HTML 5 kapcsán, viszont viszonylag keveset hallani arról, hogy a marketing dumákon kívül miről is van szó pontosan (bár korábban például már én is írtam a HTML 5-ről). A Flash leváltására alkalmas csodaszerként, a Google új fegyvereként, a HTML webkettőjeként szokás emlegetni, holott a történet egész másról szól. Egy néhol száraz, de igen érdekes specifikációról. Sőt, a HTML 5 mellett itt van a CSS 3, és itt van az SVG és egyéb más lehetőségek is. Egy több bejegyzésből álló sorozatban megpróbálom összeszedni, hogy mi is volt a HTML 5 és a CSS 3 története, hogy pontosan milyen új eszközöket kapunk ezekkel a specifikációkkal, s hogy hol tart most ezeknek a böngészőkben implementálása.

html-5-fifth-element

HTML 5 – így történt

A Wikipédia HTML 5 szócikke nem túl bőbeszédűen, de egész jól összeszedi, hogy hogyan is jutottuk el a HTML 5 mai állapotáig. Az egész a WHAT Munkacsoport (Web Hypertext Applications Technology Working Group) megalakulásával kezdődött 2004 júniusában, pár hónapos előkészítő munka után. A csoport alapítói az alternatív (IE-hez képest) böngészőgyártók, konkrétan az Apple (Safari), a Mozilla Alapítvány (Firefox) és az Opera Software (Opera) voltak, céljuk egy a W3C-tól független, annál hatékonyabban működő, nyitott, laza összefogás volt. A Microsoft eleinte ki lett hagyva a játékból, később pedig egy ideig még nem ismerte el a törekvéseket, de az IE 8 kapcsán már elkezdett implementálni részleteket, és az IE 9-ben további implementációk várhatóak. A W3C akkoriban nem a rugalmasságáról volt híres, a (nem alacsony tagdíjat fizető) tagok vehettek csak részt a döntésekben és az irányok meghatározásában, és sokkal inkább az akadémiai hozzáálláson, mint a praktikumon volt a hangsúly. A problémák a W3C ajánlásokban szereplő, de a böngészőkben nehezen megvalósítható, vagy egyszerűen csak nem használt funkciókban (lásd például a CSS 2.1 megjelenésének oka, vagy az XHTML 2.0 teljes csődje) jelentkeztek.

A WHATWG a Web Forms 2.0, Web Apps 1.0 és Web Controls 1.0 dokumentumok elkészítésével kezdett el foglalkozni. A Web Forms célja a HTML 4.01-ben definiált form elemek olyan jellegű bővítése volt, melyek a régi böngészőkkel is kompatibilisek, de igazodnak a kor igényeihez, és JavaScripttel a régi böngészőkben is megvalósíthatóak. A Web Apps egy sokkal összetettebb, a webalkalmazásokat támogató, már létező és teljesen új fejlesztések szabványos irányba tereléséről szólt. Új HTML elemektől kezdve a session kezelés, a helyi adattárolás, WYSIWYG szerkesztés, 2D és 3D canvas, különböző kommunikációs megoldások és további kisebb-nagyobb fejlesztések mind a HTML leíró nyelvet, mind pedig a DOM-ot illetően az, amit magába foglalt a specifikáció. Végül a  Web Controls célja olyan lehetőségek definiálása volt, melyek lehetővé tennék új “widgetek”, kvázi HTML elemek definiálását és működésének leírását.

Az új ajánlások közzététele és tervezése eleve a W3C ajánlások formátumával kompatibilis módon zajlott, és célként volt kitűzve, hogy amennyiben lehetséges, a W3C fogadja majd be a dokumentumokat. A szabványok kialakítása ezután nagy lendülettel elkezdődött, új elemek is beléptek, és volt olyan is, amiről kiderült, hogy mégsincs rá szükség, és 2006-ban indult egy blog is, mely folyamatosan beszámol azóta is a fejleményekről. 2007-ben a W3c bejelentette, hogy újra nekifut a HTML történetnek, ekkor már nyílt levelezőlistával, és határozottan együttműködve a WHATWG-vel is.

A Web Apps 1.0-ba végül beleolvadt a Web Forms 2.0, és átnevezték HTML 5-re, a Web Controls pedig időközben elhalt a nem túl nagy érdeklődés, illetve a hasonló célú XBL 2.0 miatt.

HTML 5 – itt tartunk

A HTML 5 fejlesztése kifejezetten aktív. A specifikálás azóta sem állt meg, s bár elég jól körvonalazódott már a HTML 5 tartalma, továbbra is előfordulhat, hogy új elemek kerülnek be, vagy kikerülnek kevésbé fontos elemek, sok részlet pedig folyamatosan finomításra kerül. A böngészőgyártók elkezdeték implementálni a különböző lehetőségeket, összességében elmondható, hogy az összes szóba jövő böngésző jó úton halad, s még ha az Internet Explorer le is van maradva, de a legtöbb dolog ebben a böngészőben is implementálva lesz szépen lassan.

Egy bekezdésben nehéz lenne összefoglalnom, hogy mennyi részlete van a specifikációnak, nagyon-nagyon komplex. Nagyon sokat lehet tanulni belőle nem csak a jövőről, de arról is, hogy most hogyan működnek a böngészők és úgy általában a web, hiszen a céljai között az eddig nem dokumentált, de az évek során kompromisszumos megoldásként összeállt viselkedések definiálása is szerepel. A dokumentum nem csak a HTML elemeket, hanem a DOM lehetőségeit, illetve egyéb, a HTML feldolgozásához, megjelenítéséhez kapcsolatos részleteket is leír. Íme egy önhatalmúlag összeállított kivonat:

  • oldalvázat, szekciókat leíró elemek: body, section, nav, article, aside, h1-h6, hgroup, header, footer, address
  • új szöveges elemek, mint például: time, progress, meter
  • új tartalmat beágyazó elemek, mint például: figure, video, audio, source, canvas, map
  • az újfajta beviteli mezők, form elemek és a komplex formok leírását lehetővé tevő jelölők, elemek
  • interaktívitást lehetővé tevő elemek: details, command, menu
  • microdata – adatok HTML-be ágyazásának és kiolvasásának módja
  • a HTML és a JavaScript kapcsolatát, események működése
  • offline alkalmazások létrehozásának lehetősége
  • linkek, kapcsolódó tartalmak leírásának (feedektől a nofollow-on át a faviconokig) módja
  • a felhasználói interakcióval kapcsolatos lehetőségeket, mint például: szöveg kiválasztása, WYSIWYG szerkesztés lehetősége, helyesírás ellenőrzés, drag’n'drop
  • kommunikáció különböző domainek között az oldalon belül és a külvilággal
  • HTML vs. XHTML kérdést és a feldolgozás mikéntje
  • a megjelenítés az alapvető kérdésektől a betűtípusok kezeléséig
  • az idejétmúlt elemeket mint például: applet, marquee, frame, DOM lehetőségeket és az ezekkel kapcsolatos hibakezelést

Elég szabadon válogattam a dokumentumból részleteket, de a lista hosszúságából talán látszik, hogy nem egy 5 perces olvasmányról van szó, s hogy a böngészőgyártók elé igen komoly feladatok vannak kitűzve. Hogy tovább árnyaljam a képet, az olyan lehetőségek például, mint a canvas elem, itt a felsorolás egyik pontjában egy belső felsorolás részeként szerepelnek csak, holott egy könyv teljes fejezetét, vagy akár egy könyvet is lehetne szentelni a témának.

CSS 3 – így történt

A CSS 3 egy egészen más utat járt be, a kezdetektől W3C projektként fut. Itt is érdemes elolvasni a Wikipedia CSS bejegyzését, jól mutatja be a CSS múltját. A CSS 2 1998 májusában jelent meg, de a böngészők már ekkor komoly lemaradásban voltak, a Macintoshra kiadott Internet Explorer 5.0 a CSS első változatát is csak két évvel a második változat kiadása után, 2000-ben implementálta, és ezzel az első, legmodernebb böngésző volt akkor. A második változatot évekkel később sem tudta egyik böngésző sem megvalósítani teljes egészében annak viszonylagos összetettsége miatt. A helyzet normalizálása érdekében hozta ki a W3C a CSS 2.1-es változatát, mely alapvetően egy butított megvalósítás volt, a praktikumot előtérbe helyezve, és igazodva az akkori böngészőkhöz kihagyták belőle a “megvalósíthatatlan” részeket.

Tanulva a hibáiból a CSS 3 immár modularizált lett, vagyis különböző funkciók mentén modulokra robbantották az újdonságokat, melyeket a böngészők így “csomagban” tudnak megvalósítani, vagy akár átmenetileg figyelmen kívül hagyni. A CSS 3 egyes moduljai közel végleges, más moduljai kezdetleges állapotban vannak (helyzet), hatalmas mozgolódás nincs is ezirányban a specifikáció terén (a teljesen hiányos roadmap), havonta egy-két dokumentum frissül. Az implementációt illetően a böngészőgyártók bár nem rohannak, de jó ütemben implementálják az érdekesebb modulokat, adott funkciókat egész jól valósítanak már meg, sok dolog van még így is hátra.

A CSS 3 fejlesztése is sokkal nyitottabb folyamat már, mint korábban volt, a levelezőlistához bárki csatlakozhat, és véleményt, javaslatokat formálhat az irányokról, problémákról.

CSS 3 – itt tartunk

A CSS 3-nak vannak izgalmas, már-már eszement részei is, érdemes átfutni a specifikációt, és ismerkedni egy kicsit a várható irányokról, de ezeket én is igyekszem majd összefoglalni. Ahogy a HTML 5-nél, itt is összeszedtem egy listát, mely a CSS 3 különböző moduljait, és azok szerepét foglalja össze:

  • CSS Template Layout: a CSS 2.1-ben “nincs” olyan elem, mely oldalak layoutjának leírására, meghatározására szolgálnak (a float-ok ilyen célú használata például egy kompromisszum csak), a CSS Template Layout ezt a hiányosságot próbálja meg orvosolni. Elsőre elég vad és szokatlan, de mégis hatékonynak tűnő leíró megoldással.
  • CSS Aural Style Sheets: a CSS alapvetően a vizuális megjelenítésről szól, ez a CSS 3 modul viszont azt írja le, hogy hogyan lehet hangokat kapcsolni a dokumentumokhoz, illetve az eseményeihez (hover, oldal betöltődés, stb.), továbbá hogy hogyan lehet ezeknek a hangoknak a különböző tulajdonságait befolyásolni (balansz, hangerő, stb.).
  • CSS Backgrounds and Borders: a CSS 2.1 szabvány viszonylag puritán lehetőségeket kínál egy adott block megjelenésű elem hátterének és keretének beállításához. Ez a modul azt írja le, hogy hogyan rendelhetünk akár több háttérképet is egy elemhez, hogy hogyan állíthatjuk be azok pozícióját, kivágását és torzítását, illetve a kereteket illetően hogyan lehet a vonalak helyett képeket használni, vonalas keretet hogyan lehet lekerekíteni, s hogyan lehet árnyékot beállítani.
  • CSS Basic User Interface: formok különböző állapotaival kapcsolatos kiválasztók (Web Forms 2.0-hoz kapcsolódóan), a kerethez hasonló outline, egérkurzorok – az alapvető felhasználói interfész elemekről szól ez a modul.
  • CSS Basic Box Model: szintén alapvető dolgokkal foglalkozó modul, mely a doboz modellről szól, a display tulajdonság különböző értékeiről, a float és clear hatásáról és viselkedéséről, az overflow-ról és hasonló témákról. Az eddig használt, de részleteiben nem definiált, az IE overflow-x, overflow-y lehetőségének “legalizálásáról” és teljesen új dolgokkal is foglalkozik ez a modul.
  • CSS Extended Box Model: ami nem fért bele a  Basic modellbe – egyelőre ebben a modulnak még nem kezdődött el a publikus kidolgozása sem
  • CSS Marquee: animált üzenősáv lehetőségek leírását teszi lehetővé, a doboz modell moduljából vált ki.
  • CSS Cascading and Inheritance: ez a modul az olyan alapvető szabályokról, mint az öröklődés, egymásba ágyazás, különböző médiák kezelése szól, alapértelmezett értékek, szabályok súlyának számítása szól. Alapvetően az eddig nem tisztázott, de nagyjából ugyanúgy működő megoldások pontos dokumentálása a célja, nagy újdonságokat nem hoz be.
  • CSS Color: a színek leírásának módjáról szól, ami újdonság benne, az legfőképpen a “negyedik dimenzió”, avagy a áttetszőség mint “szín” komponens kezelése.
  • CSS Fonts: a betűkészletek kezelését foglalja magában ez a modul, újdonságot a betűtípusok méreteinek egymáshoz igazításával és a “letölthető”, avagy a felhasználó gépén nem jelen levő betűkészletek használhatóságával kapcsolatban hoz.
  • CSS Generated Content for Paged Media: a Paged Media modulon felüli lehetőségek “oldal alapú” médiákhoz, mint például egy nyomtatott dokumentum verzió, vagy akár egy prezentáció. Olyanok vannak benne, mint dinamikus hivatkozások a dokumentumon belül (”lásd a 25. oldalon”), vagy például az oldal fejlécének/láblécének beállítása a dokumentum h1/h2/h3 (vagy bármilyen más) elemeinek segítségével.
  • CSS Generated and Replaced Content: oldal tartalmak létrehozásáról, vagy cseréjéről szóló modul, “hivatalosan” ezzel lehet például egy szöveges fejléc elemet képre cserélni, vagy adott elemek elé/mögé beszúrni tartalmakat
  • CSS Hyperlink Presentation: a linkek megjelenéséért, viselkedéséért felelős, például hogy mikor számít “aktívnak” egy link, de az is leírható a modulban foglaltak segítségével, hogy hol (új ablak, fül, stb.) nyiljon meg egy link.
  • CSS Introduction: ez egy összefoglaló modul, ami egy bevezetést, áttekintést (fog) adni a CSS 3 lehetőségeiről – majd ha “kész” lesz.
  • CSS Line Layout: a sorok függőleges igazítását, továbbá az összefüggő szövegek első karakterének, első sorának kiválasztóját írja le.
  • CSS Lists: a különböző listák megjelenésének leirhatóságát szabályozza ez a modul, a számozástól kezdve képek elhelyezéséig a listaelemek elé.
  • CSS Math: matematikai képletek, kifejezések (MathML) megjelenésének szabályozását végzi.
  • CSS Multi-column Layout: szövegek több oszlopba renderelését megvalósító modul, az oszlopok számának megadásától az elválasztó “hézag” paraméterének megadásáig lehet szabályozni a megjelenítést.
  • CSS Namespaces: az XML névtereinek támogatása CSS-ben is: a kiválasztók kiegészítése névtér támogatással.
  • CSS Object Model: a DOM “szabvány” azt szabályozza, hogy hogyan érhetőek el és módosíthatóak a HTML és XML dokumentumok “kívülről” valamilyen (pl. JavaScript) programnyelv által, ez a modul ugyanezt írja le, csak a CSS tulajdonságok kapcsán.
  • CSSOM View Module: egy dokumentum megjelenésének szabályozása valamilyen (pl. JavaScript) programnyelv által – konkrétan a dokumentum és elemek scroll pozíciójának állítása került bele ebbe a modulba, de foglalkozik a tartalmak kiválasztásával és az egér eseményekkel is.
  • CSS Paged Media: a korábban már említett modul, mely az oldalak fejlécének, láblécének, oldalak sorszámozásának állításáért felelős.
  • CSS Positioning: a position tulajdonság értékeinek pontos viselkedését szabályozó modul.
  • CSS Presentation Levels: különböző megjelenési szinteket, lépéseket definiál, például egy prezentáció egyes oldalaihoz definiálhatunk lépéseket (hányadik lépés), és megadhatjuk, hogy ha az adott lépésnél (szintnél) vagyunk, akkor mi legyen látható.
  • CSS Reader Media Type: ez a modul már megszűnt, de a különböző felolvasók támogatásáról szólt.
  • CSS Ruby: egyes írásoknál (pl. kínai és japán) léteznek az olvasást segítő “meta” írásjelek, melyek például az adott “szó” kiejtését teszik egyértelművé – ezek az úgynevezett “ruby”-k. Ezek pozícionálását szabályozza le ez a modul.
  • CSS Scoping: hogy pontosan mi is akarna lenni ez a modul, arról nem találtam konkrét információt, de a CSS Namespaces modulban létezik egy hasonló témakör – mely a kiválasztók működési területéről szól.
  • Grid Positioning: a CSS Template Layout modul is megpróbál választ adni arra a kérdésre, hogy hogyan lehet leírni egy komplex oldal layoutját, ez a modul is ezért a területért felelős, s alapvetően “grid”, azaz háló alapú layoutok leírását teszi lehetővé, kevésbé vad szintakszissal, mint társa.
  • CSS Speech: ez a modul azt szabályozza, hogy egy adott dokumentum hogyan prezentálható hang formában. Elég sok felhasználási lehetősége lehet az okostelefonoktól a navigációs rendszerekig.
  • CSS Style Attribute Syntax: a HTML (és egyéb CSS-sel szabályozott dokumentumok) “style” tulajdonságának formátumát definiálja – ez az egyik olyan alapvető dolog, ami korábban nem igazán volt szabályozva.
  • CSS Syntax: a CSS szabvány formátumának átfogó szabályozása, a leírónyelv filozófiáját foglalja magában.
  • CSS Tables Module: a táblázatok megjelenéséért felelős modul.
  • CSS Text: szövegek megjelenését szabályzó modul, az aláhúzástól kezdve a szövegek több sorra törésének leírásáig foglalja össze a terület kérdéseit.
  • CSS Text Layout: folytatja az előző modul feladatait, a függőleges írásiránytól kezdve a jobbról-balra történő írások jelöléséig.
  • CSS Line Grid: összetett szimbólumok vonalhoz igazodását leíró modul, mint például a japán szövegek karaktereinek egymás alá illesztése.
  • CSS Values and Units: a CSS értékeinek (számok, szöveges színek, URL-ek stb.) és egységeinek (px, em, ex, stb.) pontos működését és leírását szabályzó modul.
  • CSS Web Fonts: megszűnt, beleolvadt a CSS Fonts modulba.
  • Behavioral Extensions to CSS: dokumentum elemekhez viselkedések csatolását leíró modul – kvázi új dokumentum elemek hozhatóak létre a segítségével (pl. egy <ledmatrix> elemhez hozzárendelhetünk egy külső URL-en – XBL leírónyelvvel – leírt viselkedést).
  • CSS Flexible Box Layout Module Level 3: elemek box és inline-box megjelenéssel történő renderelését leíró modul.
  • CSS Image Values Module Level 3: képekre hivatkozó CSS tulajdonságok (pl. háttérkép) szabályait írja le.
  • CSS 2D Transforms Module: olyan kétdimenziós transzformációkat ír le, mint a mozgatás, nyújtás, forgatás, torzítás.
  • CSS 3D Transformations Module: perpektívikus 3D alapú transzformációkat ír le, a kétdimenziós transzformációkat ruházza fel egy harmadik dimenzióval.
  • CSS Transitions Module: átmenetek (oldal betöltődéstől kezdve a hover effektekig) viselkedését leíró modul.
  • CSS Animations Module: mozgás és egyéb animáció leírása CSS segítségével: időzítések, állapotok, késleltetések.

Nem mindegyik modult fejlesztik persze aktívan, van, amelyik több éves – vagy azért mert befejezettnek tekinthető, vagy azért, mert nem volt rá komolyabb igény. Számos aktív modulról lehet viszont olvasni manapság, ezek megvalósításánál talán a WebKit (Safari és Chrome mögött) áll az élen.

A fentiekből jól látható, hogy vannak nagyon alapnak tekinthető modulok, melyek jól kidolgozottak, és a CSS filozófiáját, pontos szintaktikáját mutatják be, vagy már évek óta használt, de eddig pontosan nem definiált részleteket szabályoznak.

Összefoglalás

Mint a fentiekből is látható, izgalmas korba születtünk. :) Jópár évnek kell eltelnie, mire a HTML 5 és a CSS 3 többségét használni fogjuk majd tudni, de sok olyan részlet van, melyeket már ma is tudunk használni, vagy mert a “gracefully degradation” jegyében a felhasználó egy tökéletesen működő, csak fapadosabb megoldással találkozik az azokat nem támogató böngészőkben, vagy pedig azért, mert JavaScript vagy más megoldásokkal azokban a böngészőkben is működőképesek lehetnek, melyek alapvetően nem támogatják még azokat. Ahol ez a helyzet, s ahol ebből nem származik komoly hátrány, ott mindenképpen javaslom az újdonságok használatát, hiszen ezzel kényelmesebbé tehető a modern böngészőket használók élete, és látványos megoldásokat lehet kihozni a dologból.

Emlékeimből, illetve a különböző dokumentumokból, blogbejegyzésekből igyekeztem rekonstruálni a történteket, ha valaki másképp tud valamit, ne hezitáljon azt jelezni egy hozzászólás formájában. Folyt. köv.

Closure Compiler

Pár napja tette elérhetővé a Google belső használatú JavaScript könyvtárainak egy részét egy hármas pakkban: a Closure Tools keretében mutatta be a Closure Compiler, a Closure Library és a Closure Templates eszközöket. Az elsőre térnék ki egy kicsit részletesebben, mert egy elég kellemes eszközt kapunk, de nézzük meg azt is, hogy mit tud a többi.

closuretools

A Closure Tools csomag tehát az alábbi összetevőkből áll:

  • Closure Compiler: egy JavaScript “tömörítő”, mely több algoritmus segítségével képes csökkenteni a JavaScript kódok méretét, illetve gyorsítani is azt.
  • Closure Library: a Google saját JavaScript könyvtára, leginkább a Dojo-hoz tudnám hasonlítani, egy a matematikai függvényektől a kommunikáción keresztül a felhasználó interfész elemekig kínál megoldásokat.
  • Closure Templates: JavaScriptben és Javaban megvalósított sablonozó

A Closure Library-re a névterek, illetve az átláthatóságot javító, de sok gépelést igénylő hosszú, angol nyelvű függvénynevek jellemzőek. Személy szerint nem szeretem ezt az irányzatot, én inkább a tömören fogalmazó leíró megoldásokat kedvelem (a Perltől a jQuery-ig), ennek ellenére érdemes vetni a lehetőségekre egy pillantást, mert ha a formátum nem is nyeri el feltétlenül mindenki tetszését, de a lehetőségek kellemesek (mondom ezt úgy, hogy a hasonló névterekkel dolgozó Dojo sohasem tudott meggyőzni).

Amiket kiemelnék a Library nem túl átlátható lehetőségei közül:

  • UI elemek: melyek segítségével a GMailben, GDocsban látható menüt, toolbarokat építhetünk, gombokat tehetünk ki és a Flasht is eltakaró dialógus ablakokat nyithatunk
  • Gyorsbillentyű kezelés
  • Helyesírás ellenőrzés
  • Gears támogatás
  • Böngésző előzmények kezelés

Persze ennél sokkal több van a függvénykönyvtár mögött, az SVN repository-ból sokminden kiderül, és ott a dokumentáció is.

A Closure Template egy sablonkezelő rendszer. Röviden csak annyit írnék róla, hogy szintén nem az ízlésem szerint való, mivel – ha jól láttam – előzetes fordítást igényel (a template-ről JavaScript, illetve Java kódra). Így valóban a lehető leggyorsabb megoldást kínálja, de fejleszteni annyira nem kényelmes a segítségével. Ha már sablonkezelő és JavaScript, akkor nekem a Trimpath-féle megoldás sokkal inkább tetszik.

A Closure Compiler viszont mindenképpen egy hiánypótló eszköz. Komoly optimalizációkat képes végrehajtani a kódon, felismerve a nem használt részeket, az egyszer használt függvényeket megszüntetve, kódrészleteket összevonva, stb.

Az egyszerű whitespace eltávolító (megjegyzések, sortörések, felesleges pontosvesszők) alapszolgáltatásnak számít más optimalizálók esetében is. A bonyolultabb optimalizálók képesek egyebekre is, mint például a változónevek rövidítésére, az objektum["tulajdonsag"] kódrészlet objektum.tulajdonsag formára hozására, stb. A Closure Compiler azonban ennél is továbbmegy, például a következő optimalizációk elvégzésével:

  • if (a) { b(); } -> a && b()
  • if (a) { b(); } else { c(); } -> a?b():c()
  • return 2*3; -> return 6;
  • var a; var b; -> var a,b;

A következő kódrészletből:

function osszeadas(a, b) {
  return a+b;
}
alert(osszeadas(3,8));

Ezt csinálja:

alert(11);

De képes azokat a függvényeket eltávolítani, melyeket nem használunk a kódunkban, így ha nagyobb függvénykönyvtárakkal dolgozunk, nem kell aggódnunk amiatt, hogy felesleges részeket is betöltünk, az optimalizáció során ezeket eldobja ugyanis a program. Itt egy még bonyolultabb optimalizációval is találkozhatunk.

A Closure Compilerről persze el kell mondani, hogy nem feltétlenül biztonságos a használata, bonyolult kódelemzést végez ugyan, de egy eval(), vagy más rossz JavaScript megoldás azt eredményezheti, hogy a végeredmény nem lesz működőképes. Ezt a megfelelő JavaScript kódolási stílus betartásával, konfigurációs paraméterek segítségével (mit engedünk, mely részekre engedjük), a kódban tippek leírásával, vagy a komolyabb tömörítések kikapcsolásával tudjuk kivédeni – értelemszerűen az előbbiek a javasoltak.

Az optimalizáló online (ingyenes), API-val is rendelkező szolgáltatásként, de parancssori eszközként is elérhető. Érdemes játszani vele egy kicsit, látványos. A Firebug kiegészítő segítségével a tömörített kódban előforduló hibákat is könnyen debuggolhatjuk, így az éles rendszerben sincsen kizárva a hibakeresés lehetősége.

Redis: a memcached gyilkos

A Szabad Szoftver Konferencián előadott prezentációm célja a Redis nevű, memória alapú key-value adatbázis lehetőségeinek bemutatása volt. Számos hasonló projekt létezik, melyekkel összehasonlítani nem fért bele sem ennek a blogbejegyzésnek, sem az előadásom kereteibe, mindazonáltal megpróbálok egy képet adni arról is, hogy milyen egyéb lehetőségek vannak.

redis

Frissítés #1: Íme az előadásom fóliái (kicsit más infókat tartalmaznak, mint az alábbi írás, például azt is, hogy milyen lehetőségek lesznek az 1.1-es, illetve jövőbeli Redisekben:

Először a key-value adatbázisokról lesz szó, majd arról beszélek, hogy milyen gondolatiság van ennek a filozófiának az újbóli fellángolása mögött, és miért is aktuális ez a téma manapság, miért célszerű megismernünk minél több lehetőséget ezirányban. A bejegyzés másik felében pedig a Redis lehetőségeit mutatom be a funkcióitól a backupolási lehetőségekig, s szó lesz majd egy esettanulmány jellegű rész keretében arról is, hogy milyen gondolkodásmóddal tudjuk hatékony módon kihasználni a Redis, illetve a hasonló projektek lehetőségeit.

NoSQL, key-value adatbázisok

Egyre divatosabbnak számít manapság adatbázisok oly módon történő megvalósítása, ahol az SQL lekérdezőnyelv nem játszik szerepet. A NoSQL “mozgalom” mögött az a gondolatiság rejtőzik, hogy minél egyszerűbb eszközökkel, minél terhelhetőbb, skálázható, illetve stabil adattárolást valósítsunk meg. A relációs adatbázisok ugyan nagyon sok problémára választ kínálnak, de ez bonyolultságot hoz, s ebből adódóan vesztik el rugalmasságukat, illetve ez az, ami sebességük kárára is válik. Azzal együtt, hogy a bonyolultságból visszavéve, egyszerű adatbázis sémákkal dolgozva gyors megoldások építhetőek relációs modellben is, vannak olyan céleszközök, melyeket nem lehet csak egy kézlegyintéssel elintézni.

Az igényt a nagy látogatottságú, terhelt webes szolgáltatások, a “cloud” témaköre hozta, ebből az irányból származnak azok az elvárások, melyek például a MySQL egyszerűsítését zászlajára tűző Drizzle projekt születését is lehetővé tették, illetve hoztak képbe, tesznek populárissá olyan technológiákat, melyeknek már régóta birtokában vagyunk, de kevésbé használtuk őket szélesebb körben.
A key-value adatbázis fogalma nem mai találmány, sőt, az egyik legegyszerűbb adatmodellről van szó, melyet az összes programozó ismerhet. A legtöbb modern programozási nyelvben jelen levő hashek, asszociatív tömbök, szótárak ezt az adattárolást valósítják meg. A key-value adattárolás lényege, hogy az adatbázis tartalma úgynevezett kulcsok segítségével hozzáférhető, a kulcsokhoz jellemzően egyszerű adatstruktúrával rendelkező értékeket párosítva. Az adatbázis tartalma semmilyen más módon nem kérdezhető le, alap esetben nem tudunk szűrni, rendezni adatokat, csak és kizárólag a kulcsok jelentik a hozzáférési pontot, melyek segítségével viszont nagyon gyorsan férhetünk hozzá a hozzárendelt információhoz. A képet persze árnyalja, hogy egyes megvalósítások – így az előadásom témáját adó Redis is – ezt kiegészíti különböző irányokban, ezáltal bizonyos feladatokra, problémákra hatékony megoldást kínálva a több szereplőhöz képest.

A key-value reneszánszát könnyű lenne elintézni úgy, hogy csak egy újabb hype-ról van szó, de alapvetően inkább egy tudatosabb, céleszközökkel dolgozó, a nagyobb látogatottságot hatékonyabban kiszolgálni akaró, illetve olyan funkciók megvalósítását lehetővé tenni akaró internet korszakába léptünk, melyekre jó választ ad ez a technológia (többek között). A key-value megoldást használó szerverek pedig gombamódra válnak nyílt forráskódú projektek keretében elérhetővé, így rendkívül olcsó és jól használható megoldást adva a webfejlesztők, szolgáltatás fejlesztők kezébe – azzal együtt, hogy bőven van még mindig olyan terület, ahol a hagyományos relációs modell sokkal jobb, hatékonyabb megoldást kínál.

Redis

Az előadásom címében a Redist memcached gyilkosnak neveztem, mivel számos tekintetben többet nyújt annál úgy, hogy megtartja annak előnyeit is.

A Redis egy key-value adattárolást megvalósító, az adatokat memóriában tároló, de perzisztensen háttértárra írni képes, az értékek tekintetében nem csak egyszerű sztringeket, de összetettebb listákat, halmazokat atomi műveletekkel is támogatottan megvalósító adatbázis, mely replikációra is képes.

Rendkívül dinamikusan fejlődő projektről van szó, mely pár hónap alatt jutott el az 1.0-s kiadásig úgy, hogy már korábban is stabilan használható megoldást kínált. Hamarosan várható az 1.1-es kiadás is, mely további újdonságokkal, lehetőségekkel szolgál. A projekt igen jól dokumentált, számos programozási nyelven érhető el kliens szoftver hozzá.

A key-value adattárolás mivoltát az előzőekben már tisztáztam, de nézzük, hogy a többi funkció mit is jelent. A Redis a memóriában tárolja az összes adatot, amiből egyenesen következik az is, hogy maximum annyi információt tudunk segítségével letárolni, amennyi belefér a szerver memóriájába. Mivel járulékos információk is letárolásra kerülnek, ezért figyelembe kell venni, hogy 1 GB memóriába nem tudunk 1 GB-nyi adatot letárolni, csak kevesebbet. A pontos overhead jelentősen függ attól, hogy milyen adatokkal dolgozunk, a Redis FAQ-jában olvasható példa szerint rossz esetben akár 84%-os veszteséget is jelenthetnek a különböző indexek (ez egy elég elrettentő szám, ennél sokkal jobb százalékok is kihozhatóak, mivel duplikált értékeket képes felismerni a Redis, illetve az értékeket tömöríteni is tudja), persze ez korántsem a jellemző arány, sokkal inkább a 10-20% overhead a jelemző.

A Redis az adatokat képes a háttértárra is kiírni, ezáltal perzisztens adattárolást megvalósítva. Az adatok kiírásának folyamata jól hangolható, megadhatunk intervallumot (pl. 5 percenként), írások számát (pl. minden 10.000 írás) is, de mindezeket vegyesen is be lehet állítani. Adat kiírást kezdeményezni lehet menet közben is bármikor. Az adatok kiírása közben a szerver kiszolgálja a kéréseket, nem áll meg, de a háttértárra kiírt adathalmaz konzisztens marad, s a kiírás kezdeti pillanatának állapotát tartalmazza.

Az összetett adattárolást illetően nem csak sztringek tárolhatóak el a Redis adatbázisában értékként, hanem támogatva vannak a listák és a halmazok is. Ez azt jelenti, hogy listákhoz, halmazokhoz különböző műveletek segítségével atomi módon tudunk például hozzáadni vagy lekérdezni elemeket, s ezekhez különböző parancsokat is kapunk (lásd később). További adatszerkezetek is tervbe vannak véve a Redis következő verziójának megjelenésével.

Ami a replikációt illeti, a Redis több szerver között is fenn tud tartani konzisztens adat állapotot. A replikációhoz szükséges szinkronizálást önállóan, beavatkozás nélkül képes beindítani, illetve fenntartani.

A Redis ezeket a funkciókat nagyon gyorsan képes kivitelezni, másodpercenként százezer feletti írásműveletet, illetve százezerhez közeli olvasási műveletet lehet megvalósítani a segítségével egy átlagos szerveren. Ami a konfigurálást, telepítést illeti, nagyon gyorsan, szinte nulla konfigurációval üzembe állítható a szerver szinte fapados módon, és egyből tesztelhető, kipróbálható. A parancsai egyszerűek, s gyorsan tanulhatóak, s egy kiváló, stabil eszközt ismerhetünk meg egy rövid ismerkedés során.

Hasonló projektek

Ami a memcached-del történő összehasonlítást illeti, az eddig leírtakból talán látható, hogy miben nyújt a Redis többet a Memcached szolgáltatásainál. Legfőképpen az összetett adatszerkezetek, illetve a perzisztens adattárolás lehetnek azok a funkciók, melyek miatt érdemes lehet váltani, de persze az igényektől függ, hogy ez szükséges-e. A Memcached-del szemben a Redis segítségével nem csak cache megoldásokat, hanem akár “igazi” adattárolást is megvalósíthatunk, mely egészen más felhasználási módokat is lehetővé tesz, a Memcached lehetőségeinek megtartása mellett.

Létezik egy MemcacheDB nevű projekt is, mely valójában csak nevében és protokolljában rokon a Memcacheddel, hiszen a netes interfész megvalósítását annak protokolljával kompatibilisen valósították meg, az adattárolása azonban nem a memóriában történik, hanem a BerkleyDB projektet használja erre a célra. Tekintettel arra, hogy írás műveleteknél itt minden alkalommal háttértárra írási művelet valósul meg (az mondjuk nagyon gyorsan), illetve hogy a BDB is csak egyszerű adatszerkezeteket támogat, ezért a Redis ezzel a projekttel szemben is előnyösebb választás lehet.

Támogatott nyelvek

A Redishez rövid pályafutása alatt a közösség jóvoltából (illetve a jól dokumentált protokolljának köszönhetően) számos programozási nyelven készült kliens, illetve további nyelvekhez viszonylag egyszerűen implementálható kliens megvalósítás. Ruby, Python, PHP, Erlang, Tcl, Perl, Lua, Java és Scala nyelvek alkotják a hivatalos listát, az egyetlen hiányzó ismertebb nyelvcsalád a .Net vonal. Egyes nyelvek alá (Ruby, Perl…) nem csak a parancsokat megvalósító, de komplexebb rutinkönyvtárak is rendelkezésre állnak.

Parancsok

A Redis parancsait négy csoportba sorolnám, vannak az alap-, a lista és a halmaz műveleteket megvalósítóak, továbbá az egyéb, legfőképpen adminisztrációs célúak. Persze ez elég önkényes besorolás, a projekt wiki oldalán specifikusabb kategorizálással találkozhatunk. Íme a fontosabb műveletek.

Az alapműveletek közé a következőket sorolnám:

SET kulcs érték: beállít egy új értéket a kulcs kulcshoz
GET kulcs, MGET kulcs1, kulcs2, kulcs3...: egy, illetve több kulcs értéke kérdezhető le
EXISTS kulcs: definiált-e adott kulcsú elem?
INCR kulcs, DECR kulcs: az adott kulcs numerikus értékének növelése, illetve csökkentése 1-gyel
INCRBY kulcs érték, DECRBY kulcs érték: mint az előző, de konkrét értékkel növelés, illetve csökkentés
DEL kulcs: adott kulcsú elem törlése az adatbázisból
KEYS minta: a “minta” mintával kezdődő kulcsok nevének lekérdezése
RANDOMKEY: egy véletlenszerű elem értékének lekérdezése
RENAME régikulcs újkulcs: kulcs átnevezése
EXPIRE kulcs másodperc: az adott kulcshoz lejárati idő társítás

A SET, GET, INCR/DECR műveletek sztring értékű kulcsok esetében használhatóak. Értékadás jellegű műveleteknél, ha egy kulcshoz eddig nem volt érték letárolva, akkor a Redis nem reklamál, hanem létrehozza az adott kulcsot, ez a tapasztalatok alapján így praktikus művelet.

Az EXPIRE művelet viszonylag egyedi módon megvalósított, ugyanis amennyiben egy adott kulcshoz lejárati időt társítunk, legközelebbi olvasást és írást is tartalmazó műveletkor (például INCR) a korábbi érték megsemmisül, avagy hiába nem járt még le a kulcs, de nulla értékről indul ezeknél a műveleteknél. Ez a replikáció konzisztensen tartása  miatt működik így.

A listaműveletek közé az alábbiak sorolhatóak:

RPUSH kulcs érték, LPUSH kulcs érték: az adott kulcsú listába új elemet szúr érték értékkel, jobb oldalra, illetve bal oldalra
LLEN kulcs: lista hosszának lekérdezése
LRANGE kulcs kezdet vég: lista egy adott szakaszának lekérdezése
LTRIM kulcs kezdet vég: lista csonkolása csak a megadott szakasz megtartásával
LINDEX kulcs index: adott indexű elem lekérdezése a listából
LSET kulcs index: adott indexű elem értékének módosítása a listában
LREM kulcs darab érték: adott értékű, maximum “darab” darab elem eltávolítása a listából
LPOP kulcs, RPOP kulcs: listából egy elem kiemelése bal, illetve jobb oldalról

A lista pozíciók (kezdet, vég) megadásakor negatív számok is használhatóak, a “-2” érték hátulról a második elemet jelöli.

A halmaz műveletek igen érdekes felhasználási lehetőségeket rejtenek:

SADD kulcs érték, SREM kulcs érték: adott értékű elem halmazhoz adása, törlése
SPOP kulcs: egy véletlenszerű elem kivétele a listából
SMEMBERS kulcs: halmaz elemeinek a lekérdezése
SMOVE kulcs1 kulcs2 érték: az adott érték egyik halmazból a másikba történő mozgatása
SCARD kulcs: adott halmaz tagjainak száma
SISMEMBER kulcs érték: adott érték eleme a halmaznak?
SINTER kulcs1 kulcs2 kulcs3...: halmazok metszetének lekérdezése
SINTERSTORE célkulcs kulcs1 kulcs2 kulcs3...: halmazok metszetének lekérdezése, és letárolása a “célkulcs”-ú halmazba
SUNION kulcs1 kulcs2 kulcs3...: halmazok összegének lekérdezése
SUNIONSTORE célkulcs kulcs1 kulcs2 kulcs3...: halmazok összegének lekérdezése, és letárolása a “célkulcs”-ú halmazba
SDIFF kulcs1 kulcs2 kulcs3...: halmazok különbségének lekérdezése
SDIFFSTORE célkulcs kulcs1 kulcs2 kulcs3...: halmazok különbségének lekérdezése, és letárolása a “célkulcs”-ú halmazba

Egy halmazban egy adott érték csak egyszer szerepelhet, ha megpróbálunk hozzáadni egy már szereplő értékű elemet a halmazhoz, akkor a művelet “sikertelen” lesz (hozzáadáskor válaszul megkapjuk az információt, hogy mennyi elem lett sikeresen hozzáadva a halmazhoz).

Egy elég összetett lehetőségeket kínáló, a rendezés gondolatára felépített művelet is elérhető, mely listákkal és halmazokkal is működik:

SORT kulcs
SORT kulcs DESC
SORT kulcs LIMIT 0 10 ALPHA DESC
SORT kulcs BY suly_*
SORT kulcs BY suly_* GET object_*

A művelet adott kulcs elemeit képes rendezni (növekvő, csökkenő sorrendbe, numerikusan és alfanumerikusan), s limitálható az eredményhalmaz is a LIMIT kifejezés hozzáadásával. A BY kulcsszó segítségével bár a kulcs elemei lesznek rendezve, de nem a saját értékük szerint, hanem a BY által megadott prefixhez hozzáfűzött értékük szerinti kulcs értékét véve. Ha a GET kulcsszót is megadjuk, akkor válaszként nem az adott kulcs elemeit fogjuk visszakapni, hanem a GET által megadott prefixhez hozzáfűzött értékük szerinti kulcsok értékét.

A SORT funkció nem tud csodát művelni ami a sebességet illeti, gyorsrendezés az algoritmusa. Alfanumerikus rendezéskor a LC_COLLATE környezeti változó értékét veszi figyelembe.

További érdekesebb műveletek:

DBSIZE: adatbáziselemek számának lekérdezése
TYPE kulcs: kulcs típusának (sztring, lista, halmaz) lekérdezése
SAVE, BGSAVE, LASTSAVE: háttértárra mentéssel kapcsolatos műveletek

Nem az összes műveletet mutattam be, de a Redis által biztosított lehetőségek talán jól láthatóak ezen felsorolás után. Egy átgondolt, biztos alapokon álló fejlesztésről van szó, mindegy parancs esetén use-case indokolja meglétét, illetve csak olyan parancsok állnak rendelkezésre melyek legtöbb esetben gyorsak, vagy melyek nem feltétlenül gyorsak, de a funkcionalitáshoz sokat hozzátesznek.

Nem vettem bele a felsorolásba, de a Redis több adatbázist is támogat, melyeket sorszámokkal lehet elérni, s alapból 16 áll rendelkezésre. Ezek leginkább névtérként működnek, ezek között a névterek között is lehet kulcsokat mozgatni igény szerint. Használatuk helyett inkább több Redis szerver indítása (különböző portokon) lehet javasolt, tekintettel arra, hogy így az adatbázis mentések is elkülönülnek, hogy többprocesszoros szerveren a Redis egyszálas futtatási környezete így jobban megoszlik a processzorok között, egy esetleges blokkoló művelet csak egy adott Redis szervert tart fel, s mert talán egyszerűbb a nyilvántartása egy portnak, mint egy Redis adatbázis sorszámnak.

Backup

A Redis perzisztens módon háttértárra, konkrétan egy darab fájlba írja adatbázisának tartalmát a konfigurációban meghatározott időpontokban, események bekövetkeztekor. Ez a fájl a memória tartalom egy speciális, gyorsan kiírható, illetve gyorsan beolvasható lenyomata, más célokra nem használható – nem valami egyszerű fájlformátum, hanem tömény bináris fájl.

A kimentett tartalom backupolása igen egyszerű: csak le kell másolni a fájlt. Ez akár menet közben is történhet, a szerver leállítása nélkül, még akkor is, ha éppen egy háttértárra mentési folyamat fut éppen. A Redis egy átmeneti fájlt hoz létre, és a rename nevű parancs segítségével írja felül a korábbi fájlt, így biztosítva azt, hogy az átnevezés csak akkor történik meg, ha a fájlba írás véget ért, és sikeres volt. A művelet atominak számít, tehát vagy sikeresen megtörténik a régebbi fájl felülírása, vagy sikertelen lesz a művelet, s a korábbi fájl nem sérül.

Backupolni ezen kívül egy master-slave replikáció beállításával is lehet, egy slave adatbázison, így még az I/O műveletekkel sem terhelve a fő szervert.

Replikáció

A Redis replikációja egy elég egyszerűen konfigurálható, master-slave felállású replikáció, mely lehetővé teszi több slave használatát is, illetve a slave-ek láncként felfűzve (a slave is masterként viselkedik, hozzá további slave csatlakozik) gráfot is alkothatnak.
Replikáció közben a master szerver nem áll le, így egy slave kiesésekor vagy beállásakor (szinkronizáció esetén) a master továbbra is kiszolgálja a kéréseket. Ezzel szemben a slave oldalán a replikáció beindítása, a master állapotának felvétele közben nem végez műveleteket, ezzel is biztosítva az adatok konzisztenciáját.

Ha az adatbázis nem fér be a memóriába

Az adatbázisnak a Redis esetén be kell férnie a memóriába. Ennek megkerüléséhez a Redisnek nem célja segítséget adni, bár már felmerült egy olyan jövőbeni fejlesztési irány a levelezőlistán (egészen más okokból), hogy a Redis adattárolását megvalósító layer esetlegesen cserélhető lesz. Mindenesetre ha az adatbázisunk nem fér el a memóriában, akkor vagy nem tudjuk a Redist használni, vagy valamilyen adattárolási stratégiát bevezetve meg kell kerülnünk a kérdést.

Egy lehetőség, hogy a Redist csak cache-ként használjuk azokhoz az adatokhoz, melyekről tudjuk, hogy jelentős memóriát igényelnének. Ekkor ezekhez az információkhoz lejárati időt rendelünk az EXPIRE segítségével, így ha fogyóban a memória, a Redis fel fogja ezeket a területeket szabadítani, illetve maguktól is felszabadulnak egy idő után. Az írást mind a Redisbe, mind pedig a nagyobb kapacitású másik adatbázisba elvégezzük, s először megpróbáljuk a Redisből kiolvasni az információt, ha ott nem létezik, akkor fordulunk a másik háttértárhoz. Ezt a felállás mi sikeresen használjuk.

Esettanulmány: egy Twitter klón

A Redishez szinte az indulása óta elérhető egy PHP-ben írt Twitter klón forrása, mely nagyon egyszerű forráskódjával, illetve az alkalmazott stratégiákkal jól szemlélteti a Redis lehetőségeit, illetve azt a gondolkodásmódot, melyet el kell sajátítanunk, ha key-value adatbázist szeretnénk használni fejlesztéseinkhez.

Erre a gondolkodásmódra SQL múlttal nem is olyan egyszerű átállni, mert ellentmond minden ott megtanult metodikának, többek között a normalizálás szabályainak. Mindazonáltal ha végiggondoljuk hogy mi történik egy relációs adatbázisban a háttérben: látni fogjuk, hogy gyakorlatilag kevés a különbség ami a letárolt adatokat illeti, az indexek létrehozásával és redundáns tárolásával egy relációs adatbázis is hasonlóképpen működik mint amire szükség van key-value adatbázisok esetén.

A Redis wikiben található kis tutorialt érdemes végigolvasni, mivel olyan alapokkal kezd, hogy mi is jelent a key-value adattárolás a gyakorlatban, illetve mik azok az atomi műveleteket. Ebből a tutorialból emeltem ki pár gondolatot, melyek megmutatják, hogy hogyan lehet felépíteni egy összetett adatbázist.

A Twitter klón nem csak üzenetek küldését teszi lehetővé, hanem egy teljes(ebb) klónról van szó, mely a regisztrációt, a felhasználók személyes oldalát, ismerőseinek kezelését is tartalmazza.

A felhasználókat számmal azonosítja, melynek előállításához egy “global:nextUserId” kulcsú elemet használ. Új felhasználó létrehozásakor a következő parancsokat futtatja le a rendszer:

INCR global:nextUserId (ezáltal visszakapunk egy számot, pl: 1000)
 SET uid:1000:username felhasznalonev
SET uid:1000:password jelszo

Ebből a három sorból már rengeteget lehet tanulni. A kulcsok kapcsán mint látható, speciális elnevezéseket célszerű használni, “névtereket” létrehozva a kettőspontok használatával. Míg egy key-value adatbázis alapvetően nem struktúrált, ezzel a trükkel hierarchiát vezethetünk be. A felhasználó azonosító legyártásához szükséges változót a globális névtérbe, a felhasználó azonosítójához köthető információkat az “uid” névtérbe helyeztük.

Vegyük észre a párhuzamot az adatbázis táblákkal is, hasonló a helyzet, mintha egy “uid” táblában két oszlopot hoznánk létre, az 1000-es id-jú felhasználónak két oszlopa: a “username” és “password” állnak rendelkezésre. Most egy fontos design patternt tanultunk meg a key-value adatbázisokat illetően.

Mivel csak kulcs szerint érhetőek el az adatbázisunk értékei, jelenleg nem tudjuk lekérdezni azt, hogy a “felhasznalonev” felhasználóhoz milyen azonosító, milyen jelszó kapcsolódik, bejelentkezéskor, illetve a felhasználó saját oldalának kiszolgálásakor azonban erre az információra szükségünk van. Mint látható, az adatbázis tervezését jóval alaposabban végig kell gondolnunk mint egy relációs adatbázis esetén, legfőképpen azt megvizsgálva, hogy milyen módon szeretnénk a későbbiekben hozzáférni az adatbázisban szereplő információkhoz.

A felhasználónévből felhasználói azonosító létrehozását egy új kulcs létrehozásával tudjuk megtenni, relációs adatbázisok esetén erre egy index szolgált volna:

SET username:felhasznalonev:uid 1000

A Twitternél minden felhasználónak vannak követői, illetve követik is felhasználók. Itt is hasonló stratégiát kell alkalmaznunk, mint az előbb, ugyanis mind a két irányból szeretnénk lekérdezni az információt a szolgáltatás működtetésekor (kiket követ, kik követik a felhasználót), ezért két kulcsot fogunk használni felhasználónként erre a célra. Amit az adatszerkezetet illeti, a halmazok tökéletes választást jelentenek majd:

uid:1000:followers
uid:1000:following

Egy nagyon fontos adatstruktúra még hátra van, a felhasználó legfrissebb hozzászólásait szeretnénk megjeleníteni az oldalán, mondjuk visszanézhetően maximum mondjuk ezret. A hozzászólásokat egy globális névtérben fogjuk eltárolni, s a felhasználókhoz hasonlóan azonosítókkal látjuk el, s hogy lekérdezhető legyen, hogy egy adott felhasználónak milyen hozzászólásai voltak, egy listát vetünk be:

uid:1000:posts

Amikor a felhasználó hozzászól, akkor a globális lista adminisztrációja mellett ebbe a listába is felvesszük a hozzászólás azonosítóját (LPUSH), majd a listát az ezredik elem után csonkoljuk (LTRIM), hogy ne nőjön a végtelenségig. A lista “lapozhatóan” az LRANGE parancs segítségével érhető el.

A Twitter klónt bemutató wiki oldalon ennél sokkal több gondolat olvasható, de ezzel a kivonattal talán sikerült megmutatnom pár design patternt, melyek jól használhatóvá teszik a key-value adatbázisokat, illetve megmutatják azon gyengeségeit, melyek erősségként is felfoghatóak.

Összefoglalás

A fentebb írtakból talán kiderül: egy nagyon jól használható adatbázis szervert ismerhetünk meg a Redis személyében ha úgy döntünk kipróbáljuk mit tud. Gyorsan tanulható, egyszerűen használható megoldást kínál sok problémára, melyek webes alkalmazásfejlesztéskor kifejezetten hasznosak tudnak lenni.

Mi a Miner.hu projektünk keretében, illetve iWiW alkalmazásokhoz használjuk háttéradatbázisként a Redist. Az előbbihez nagyrészt cache megoldásként, a friss bejegyzések memóriában tárolására, tematikus rovatainknál pedig a friss bejegyzéseket listákban tartjuk nyilván. Eddigi tapasztalataink azt mutatják, hogy egy terhelhető, stabil, jól használható eszközt vezettünk be, melyet másnak is szívesen ajánlunk.

Netvibes Wasabi: ütni fog

Jövő héten jön a Netvibes Wasabi változata, mely több olyan újdonságot is hoz, melyekkel egy jó időre maga mögé utasíthatja a konkurenseit. A középpontban a real time Smart Reader fog állni, mely nem csak nevében ígérkezik okosabbnak a Google Readernél. Az egész mögött pedig olyan technikai újdonságok állnak, mint a Tokyo Tyrant (és Tokyo Cabinet), Pubsubhubbub és RSSCloud támogatás.

A blogbejegyzésükben három konkrét újdonságot harangoznak be:

  • “ömlesztett nézet”, avagy a Google Readerhez hasonló dátum szerint rendezett megoldás
  • gyorsabban frissülő információk (eddig több perces cache volt, most “valós idejű” frissítést ígérnek)
  • mozaik nézet cikkekhez, képekhez, fotóblogokhoz

A mozaik nézet biztos látványos lesz, de engem annyira nem dob fel. Az első két dolog, avagy a valós idejű frissülések, illetve az ömlesztett nézet – na ez igen komolyan felpiszkálta a fantáziámat. Illetve lesznek még itt kisebb-nagyobb dolgok, mint például a “read it later” támogatása, és hasonló funkciók. A Netvibes ugye nem csak a feedekről szól, s a Smart Reader sem csak a feedeket, hanem az összes olyan widgetet támogatni fogja, melynek lesznek “frissülései”. Ez az időjárás információktól a Twitteren át a Facebook update-ekig minden magában fog foglalni.

A Tokyo Tyrant a feed tartalmak tárolásának kapcsán áll szolgálatba, ezzel a Netvibes is letette a voksot a NOSQL törekvés mellett, hozzáteszem, hogy emellett minden egyéb információ megmaradt az eddig is jól bevált MySQL-ben. Ami a Tokyo Tyrant adatmodelljével kihívás lehetett megvalósítani, az az egyes feedek tartalmának összefésülése, és többféle csoportosításban (”doboz” nézet, a Smart Readerben “fül” nézet, és az adott felhasználó “mindentbele” nézete a feedjei alapján) megjelenítése, amihez több mint valószínű, hogy egyfajta mapreduce megoldást használtak. Persze ezt normálisan MySQL-lel is lehetetlen nehéz megcsinálni, ha komoly adatmennyiségről van szó, nem véletlen, hogy más adatmodell után néztek.

A Smart Reader egy olyan funkció, mely korábban is szerepelt már a Netvibes tervei között (mikor még ott dolgoztam), de végül az egyik legfőbb indok a halasztás mellett a megfelelő architektúra hiánya volt. Úgy tűnik, hogy a Tokyo Tyrant és valamilyen subscribe rendszer segítségétvel ezt most megtalálták. További kívánságom még egy rendes levelezőkliens lenne, illetve nem tudom, hogy az OpenSocial támogatás végülis hogyan áll – titkos vágyaim ezek lennének az eddig felvillantott megoldások mellé. Persze valószínűleg ezek nem most fognak teljesülni. :)

A hírek szerint a Wasabi a Pubsubhubbub és RSSCloud megoldásokat is támogatni fogja, Freddy Mini (CEO) prezentálta is a történetet, amiből kiderült, hogy valójában egy belső, ezekhez a megoldásokhoz hasonlító, de saját rendszert építettek ki, mely az instant frissítéseket oldja meg látványosan. A várható élményről itt egy videó:

Az architektúráról pedig itt egy nem túl sokat eláruló részlet:

netvibes-hub

Az átállás az új verzióra hasonlóképpen fog menni, ahogy korábban: az érdeklődő felhasználók accountja át lesz állítva az új verzióra (visszaállítás nem lehetséges), egy ideig béta időszakban lehet tesztelgetni és visszajelezni, majd pedig mindenkinél megtörténik a váltás.

Szemező: hasznos cuccok

Avagy ami egy webfejlesztő eszköztárában jól jöhet. Nem tudom sorozat lesz-e belőle, de most találtam pár érdekes írást, eszközt, tippet, melyeket ajánlanék további fogyasztásra.

webdevtips

Underscore

Az Underscore egy JavaScript függvénykönyvtár, mely legfőképpen a funkcionális programozást elősegítő metódusokat gyűjtötte össze. Tömörítve és gzippelve mindössze 4kB hosszú, és egyéb függvénykönyvtárakkal kompatibilis.

Dive Into HTML5

Én is éppen egy HTML 5 és CSS 3 bejegyzés sorozattal készülök, a témában ez az könyv nagyon jónak ígérkezik. A link mögött egy munkaváltozat hozzáférhető, a végleges változat majd papíron lesz megvásárolható.

Redis

A Redisről nemrég tartottam előadást, illetve hétvégén is tartok róla egy bemutatót. Nemrég megjelent az 1.0-s változat, de a fejlesztése ezzel közel sem állt le. A Redis 1.1 újdonságai közé az egész számok memóriatakarékosabb tárolása, a rendezett (súlyozott) halmaz és nem utolsó sorban értékek egyszerre történő “atomi” írása támogatása fog tartozni. A trunk verzióban már elérhetőek ezek az újdonságok. Nem tudom miért, de másnak is Májkül, Kitt és a Turbó fokozat ugrik be a Redisről és a NoSQL témakörről.

Memcache Top

Bár Memcache kisasszonnyal hamarosan szakítani fogok (Miss Redis sokkal szexibb), azért jól jöhet a memcache-top nevű projekt, mely azt mutatja meg, hogy mi történik a Memcache szerverrel éppen – hasonló megjelenésben, mint a top parancs esetén. Redisnél – ha nem is ilyen interfésszel – ez is sokkal egyszerűbb, csak be kell telnetelni, és kiadni a nem dokumentált “monitor” parancsot.

OpenSocial jQuery

Még mindig nem sikerült eljutnom odáig, hogy egy iWiW-es projektben használjam, és így rendesen megnézzem mennyire kínál jó alternatívát a sima jQuery-hez képest, de azért az OpenSocial jQuery mindenképpen érdekes lehet azoknak, akik az alkalmazásfejlesztésbe vágják a fejszéjüket.

jQuery and General JavaScript Tips to Improve Your Code

Egy tippgyűjtemény, s bár nagyon sok újdonsággal nem találkoztam benne, a második tipp egy olyan nagyon hasznos megoldást mutatott meg a jQuery-ben, amiről valamiért nem hallottam korábban.

Mu

A Mu egy JavaScript függvénykönyvtár Facebook Connect integrációhoz. Segítségével pofonegyszerűen lehet saját weboldalról a Facebook Connect lehetőségeit használni.

Startup tippek

Most jelent meg a TechCrunchon egy blogbejegyzés arról, hogy az Y combinator “befektetőcég” milyen tippeket osztott meg egy rendezvényén európai startupok számára. Érdekes tippek, így gondoltam lefordítom és kiegészítem őket a saját gondolataimmal is azt illetően, hogy mit tapasztaltam Magyarországon, illetve az elmúlt két Startup Konferencián.

startuposdi

A Minerhez jelenleg is aktívan keresek befektetőt, ennek kapcsán viszonylag jól ismerem a befektető keresés gyakorlati részeit is. Ezen kívül a Miner céljai között a saját startup kapcsán a tapasztalatok szerzése is szerepelt – ezek alapján is megvan a véleményem. Itt a lista:

  • “Saját magad indítsd be a startupod, mert ez megtanít rá, hogy hogyan csinálj pénzt. A már fix pénzügyi háttérrel induló vállalkozások meg a pénzcsinálásra, hanem a pénz elköltésére koncentrálnak.” – Ami azt illeti, Magyarországon nehezen is találsz olyan befektetőt, aki egy ötletedet finanszírozná meg. Legalább egy prototípus kell, de valami üzleti terv sem árt, és az sem, hogy legalább kis körben bizonyított a startup.
  • “Ha vannak nem ingyenes részei a szolgáltatásodnak, az rákényszerít arra, hogy jó legyél. Az emberek azzal biztosan törődnek, amiért fizettek: jó és őszinte visszajelzést fogsz kapni” – Ezzel az a gond, hogy Magyarországon olyan startupot csinálni, aminek valamilyen részéért fizetned kell, nem túl egyszerű a micropayment rendszerek bonyolultsága és drágasága miatt, és az ehhez kapcsolódó számlázással járó adminisztrációt sem kívánom senkinek.
  • “A hasznosság sokkal fontosabb, mint innovatívnak lenni. A menő dolgoknak elmúlik a varázsa, a hasznosnak nem.” – Ez az egész startupodra legyen igaz.
  • “Egy szoftvernek nincsen éles kontúrja. Így sokkal nehezebb visszafognod magad, hogy belepakolj olyan lehetőségeket is, melyeket nem kéne. Gondolj a termékedre múzeumként: csak olyan dolgokat tegyél bele, melyek igazán értékesek.” – Ha túl szerteágazó a startupod által lefedett terület, a végén egyik területen se tudsz kiemelkedőt alkotni.
  • “Nem tudsz csak egy dolgot csinálni. Minden terméknek van mellékterméke. Ezt persze egy startupnál sokkal nehezebb lehet megtalálni, mint egy fizikai gyártási folyamatnál. A 37 signalsnál például a könyvek és konferenciák votak ezek.” – Ehhez azt a gondolatot tenném hozzá, hogy ha valami kapcsán tapasztalatot szerzel, akkor ezt a tudást más környezetben, startupnál is értékesíteni lehet majd.
  • “Jól kérj bocsánatot. Lehet, hogy egy «Valóban sajnálom» elég, nem kell mindig a «Bocsánatot szeretnénk kérni az összes problémáért, amit okoztunk».” – Jól és hatékonyan kommunikálj a felhasználóiddal, sokszor nagyon sokat számít a helyes kommunikáció.
  • “Mindenhol lehetsz jó, nem csak a csili-vili California Valley-ben. Élj ott, ahol szeretnél. Ne gondold úgy, hogy el kéne költöznöd ahhoz, hogy a céged működni tudjon.” – Nem értek egyet, külföldön, Nyugatabbra sokkal több a lehetőség, a konferenciákról, meetupokról nem is beszélve. Persze a konkurencia is, és csak akkor érdekes belevágni, ha komolyan gondolja valaki. És persze valóban lehetne itthon is tenni végre valamit azért, hogy aktív konferenciáink, közösségeink legyenek.
  • “Nem kell hibáznod a sikerhez és a felnőtté váláshoz. Az amerikai és európai üzleti bukásokkal kapcsolatos toleranciát sokszor vetik össze. Lehet, kevesebbet kéne emiatt aggódnunk. A sikeres dolgok átvétele sokkal hatékonyabb lehet, mint tanulni a hibákból. És az eredmények is sokkal könnyebben megjósolhatóak.” – Itt nem arról van szó, hogy lemásoljunk egy szolgáltatást, sokkal inkább arról, hogy lássuk meg az ötleteket más szolgáltatásban. Az innováció is nagyon fontos, de belebukni nem érdemes.
  • “Európa sokkal kevésbé veszélyes hely Amerikához képest ami egy cég indítását illeti – az itteni szociális rendszer miatt. Nem fogsz éhenhalni vagy orvosi segítség nélkül maradni, hogy ha befuccsol a biznisz.” – Hát nem tudom, azért ne tegyük fel az összes pénzünket egy lapra. Mindazonáltal ha valaki ért a szakmájához, állást valószínűleg talál magának egy bukta után is.
  • “Néhány európai országban sokkal inkább néznek rád csúnyán egy látványos siker után, mintha megbuknál. Például Dániában, Hollandiában kiemelkedni a tömegből nem feltétlenül pozitív dolog.” – Hát ez ismerős, de erről inkább tudni kell, mint emiatt bármit is másképp csinálni.

Most, hogy a végére értem a fordításnak, és a tanácsok megemésztésének, összefoglalásul azt tudom leírni, hogy ugyan eget rengető és az újdonság elemi erejével ható lehet, hogy nincs köztük. Ezzel együtt az első 3-4 tipp megfogadását részemről mindenképpen javasolni tudom azoknak, akik belevágnak a saját bizniszükbe.

Internet Hungary 2009

Kedden (és szerda reggel) a szervezők meghívásának eleget téve előadóként is részt vehettem az Internet Hungary idei rendezvényén. Az oldal honlapja, a rendezvény előadásai ugyan a múlt évszázadot képviselték, az 1000 feletti résztvevő azonban aktív és érdekes eszmecserét folytatott. Az előadásom kapcsán, illetve egyéb beszélgetések során potenciális üzleti partnerekkel és lehetséges Miner befektetőkkel is találkoztam (ez egy másik történet, de volt több komoly érdeklődő is), így elmondhatom, hogy a konferencia igen hasznosan telt számomra (és az estémet még Tibi bácsi is vidámmá tette DJ tevékenységével).

A Miner.hu üzleti lehetőségeit bemutató előadásom (melyet két másik startup bemutatkozása, és egy igen rövid beszélgetés követett) jól sikerült és a terem is tele volt, páran be se fértek. Ez utóbbit persze nem volt nehéz elérni, mivel egy squash pályáról volt szó. :) Az előadásomat egyből elérhetővé is tettem, s bár valószínűleg nem jön át teljes mértékben amit szóban még hozzátettem, de íme, most itt is megtekinthető:

Web Analytics Wednesday

Tegnap este volt a Web Analytics Wednesday első budapesti rendezvénye ahol előadóként is részt vehettem. A meetupok formátumával megegyező módon szervezett eseményről van szó, amiben egyedit kínál, hogy analítikai témákról hallhatunk előadásokat, illetve hogy az előadások angol nyelvűek. A blogbejegyzésben elérhető a saját előadásom, illetve igyekszem összeszedni pozitív benyomásaimat.

A szervező Sebestyén Anna volt, akinek nemzetközi szinten vannak tapasztalatai a témáról, s egy igen jó eseményt sikerült szerveznie a Dob utca egy hangulatos borozójában, egy kis borozással fűszerezve. Az, hogy az előadások angol nyelvűek, annak alapvetően nem lenne értelme, de Anna sikeresen meghívott egy amerikai, és egy hazánkban élő, de ír előadót is, az előbbi az egész rendezvénysorozatot elindító June Dershewitz volt, míg az utóbbi a Yahoo! Magyarország hazai részlegénél analítikai szakértőként dolgozó Emer Kirrane. Rajtuk, és rajtam kívül még Tóth Benedek és Anna adott elő. A két említett előadón kívül még további magyarul nem beszélő résztvevők is eljöttek, azt sajnos nem tudom hogy a magyar ismerősökön kívül pontosan kikkel beszélgettem igen jókat. :)

Az angol nyelv gyakorlásán, illetve a kapcsolatépítésen kívül azért is igen jól éreztem magam, mert végre itthon is beindult azon rendezvények sora, ahol lehetőség adódik egy kis kitekintésre. Nem csak az amúgy sokat látott barátságos magyar arcok, hanem még barátságosabb idegenek is előfordultak, azokat az élményeket előhozva belőlem, amikkel eddig csak külföldi rendezvényeken találkoztam.

Hogy az előadásomról is ejtsek egy kis szót, a Google Analytics API-ról beszéltem, illetve a Piwik és Open Web Analytics nyílt forráskódú analítikai szoftverekről. Az előbbi segítségével – egy kis kódolással – sokkal testreszabhatóbb, használhatóbb felület állítható össze mint amit a Google Analytics mutatni tud, illetve az utóbbiak pedig a saját információim, adataim feletti szabadságot teszik elérhetőbbé úgy, hogy közben minőségben is jót tudnak adni.

Turbó fokozat: előadásom az nginx, Redis és node.JS lehetőségeiről

Szombaton “Turbó fokozat” címmel előadtam a Web Konferencián – az előadás keretében beszéltem az nginx, Redis és node.JS szoftverekről, melyek hasznos építőkövei lehetne egy gyors webszolgáltatásnak. Ha lesz egy kis időm, átírom blogbejegyzésbe is az elhangzottakat, de addig is az előadásom fóliái:

A prezentáció letölthető PDF formátumban is: Turbó fokozat (kb. 10MB)

Google Chrome plugin, ezt így ne

A Google csavart egyet a böngészőháborún, rúgva egy hatalmasat a Microsoftba, kiadta a Chrome plugint, ami egy Internet Explorer-be beépülő böngésző kiegészítő, s lecseréli a böngésző motorját a Chrome kínálta WebKitre. Sem a kiadás indoka/célja, sem pedig a kezdeményezés nem igazán szimpatikus számomra, össze is szedtem, hogy miért.

Chrome Plugin

  • A Google Wave megjelenésével indokolják a kiadást. A Google Wave nem fut Internet Explorerben, a Google nem tudta/akarta megcsinálni. Ez egy Google-től szerintem szégyen, ha az IE6-ot esetleg nem is szeretnék támogatni, egy IE8-at előrmutató lenne, s illene.
  • A Google Wave HTML 5-öt használ, az Internet Explorer ezt nem támogatja. Egyrészt a HTML 5 egy nagyon friss technológia, még csak vázlat formában létezik, egy ilyen friss technológiára építeni egy szolgáltatást meggondolatlanság. Másrészt az HTML 5 egyik lényege, hogy részben visszafele kompatibilis (pl. új szemantikus HTML elemek), egyes részeit még egy Internet Explorer is támogatja és/vagy gond nélkül lekezeli. Az olyan újdonságokra, mint a canvas elem, videó lejátszás, speciális form elemek pedig nincs is szüksége a Google Wave-nek, illetve semelyik böngészőben sem mondhatóak még kiforrott, szuperstabil megoldásnak. Jelzem, hogy pl. a videó lejátszást illetően a böngésző gyártók a mai napig nem tudtak megállapodni a támogatott kodekeket illetően.
  • Saját szabványt erőszakosan a felhasználóra kényszeríteni (ha nem rakod fel, nem tudod kipróbálni a Wave-t) még akkor sem menő, ha a Google csinálja.
  • Böngésző plugin telepítésére nem könnyű rávenni egy felhasználót. Egyetlen kivétel a Flash, melyre azt merem mondani hogy lehet építeni, sem a Silverlightnak, sem a Gearsnek, sem bármi másnak nem sikerült még olyan támogatottságot összeszednie, amire egy átlag weboldal kapcsán építhetünk. Ezen kívül pont az Internet Explorer felhasználók azok, akik nem igazán a célcsoportjai ezeknek a plugineknek, mivel vagy nem engedi a céges környezet sem alternatív böngészők telepítését, sem böngésző bővítményekét, vagy baromira nem értenek a dologhoz.
  • A böngésző pluginek terén a Google eddig nem tudott felmutatni folyamatos támogatást, és kiváló minőséget. A Gears Firefox alatt nálam rengeteget eszik, az új Firefox kiadásoknál pedig mindig várni kell, hogy megjelenjen egy új változat. Új Internet Explorer nem jelenik meg naponta, de gondot okozhat, hogy be kell várnia a felhasználónak majd a Chrome Plugint.
  • Semelyik plugin nem képes ugyanazt az élményt adni, mint a befogadó böngésző adna egy “natív HTML oldal” kapcsán. Konkrétan a jobb egérgombra nem az IE saját helyzetérzékeny menüje fog megjelenni (gondolom), a Chrome-ban sem az IE szolgáltatásai, sem a feltelepített kedvenc pluginek szolgáltatásai nem lesznek elérhetőek (szótár, helyesírás ellenőrzés, stb.).
  • A webfejlesztők és a felhasználók is csak minimálisan profitálnak a dologból. Ahelyett, hogy a Google edukálna, és egy böngésző frissítésre, új böngésző telepítésre szólítaná fel a felhasználót, egy plugin telepítésével nem vagyunk sokkal előrébb. Kevés embernek lesz fenn, a felhasználó pedig semmivel nem fog többet tudni arról, hogy vannak igazi alternatívák.

Lehet hogy néhány indok nagyon szubjektív, illetve nem áll szilárd lábakon, de összességében a lépés számomra azt jelenti, hogy a Google erőszakos, s képtelen volt megcsinálni azt, amit egy hétköznapi webfejlesztő is meg tud csinálni: az Internet Explorer támogatását saját termékében.