Redis: key-value databáze v paměti i na disku

Se sociálními sítěmi přišly i zvýšené nároky na uskladnění a filtrování obrovského množství dat. Klasické relační databáze ztrácely dech a bylo potřeba najít něco jednoduššího, co zvládne miliony požadavků za sekundu. Takových databází je celá řada. Někde uprostřed stojí Redis, a o něm si teď povíme.

Seriál: Nerelační databáze (11 dílů)

  1. CouchDB – tak trochu jiná databáze (1. část) 24.8.2009
  2. CouchDB – tak trochu jiná databáze (2. část) 31.8.2009
  3. CouchDB – tak trochu jiná databáze (3. část) 7.9.2009
  4. MySQL v roli neschémové databáze 6.1.2010
  5. Základy Amazon SimpleDB 30.3.2010
  6. Návrh databáze – NoSQL vs SQL 31.3.2010
  7. Amazon SimpleDB prakticky v PHP 15.4.2010
  8. Vyskúšajme si Tokyo Cabinet 4.5.2010
  9. Redis: key-value databáze v paměti i na disku 7.10.2010
  10. Přechod z MySQL na CouchDB, část první 17.2.2011
  11. Přechod z MySQL na CouchDB: Druhý díl 24.2.2011

Redis? Prosím?

Redis je klasickou key-value databází, což, jak pravděpodobně víte, znamená, že pod jeden klíč se uloží jedna hodnota. Postupem vývoje se dostal dál a pod jeden klíč je možné uložit několik datových struktur, které v ledasčem pomohou. Aktuální verze 2.0.2 pracuje s pěti datovými strukturami, jimiž dobře kopíruje požadavky dnešních aplikací.

Zmínil jsem, že Redis stojí uprostřed a má to svůj důvod, data totiž uchovává primárně v paměti, a díky tomu je rychlý jako blesk. Obsah paměti je podle konfigurace ukládán na disk, takže když se něco stane, pravděpodobně o nic nepřijdete, nebo jen o „pár“ klíčů. Ukládání se provádí zapisováním do nového souboru, který je po skončení přejmenován na správné jméno. Přejmenování, resp. přesun je atomická operace, takže buď je soubor přejmenován, nebo není a nic mezi tím neexistuje. Určitě je ale dobré počítat s nejhorším a pokud máte alespoň trochu možnost, použijte dvě instance Redisu, nahoďte mezi nimi replikaci a také zapněte Append Only File.

Redis naštěstí už není omezen jen velikostí RAM a od druhé verze umí využít i swapovací soubor a do něj ukládat některé nepoužívané hodnoty. I tak jsou ale tato data oddělena od jejich persistetních kopií a když dojde na ukládání dat na disk, dělá se kopie i těch, které se na disku již nacházejí. Při zvažování, jestli je Redis ideální pro váš projekt, také počítejte s tím, že klíče jsou drženy v paměti vždy. To znamená, že když vám dojde paměť a všechny hodnoty už jsou uloženy na disku, Redis odmítne vytvořit nový klíč.

V praxi

Na Redis jsem narazil, když jsem potřeboval cache pro administraci hostingu. Tam jsem se často přes SSH dotazoval serveru na nějaké informace. Ty se většinou během času nějak razantně nemění a nebo na aktuálnosti tolik nezáleží (seznam uživatelů, velikost zabraného prostoru, existence toho a toho adresáře, …), navíc jde u důležitých parametrů dobře rozhodnout, kdy cache zahodit a kdy brát data z ní. Jinými nástroji, než jsou v administraci, se do serveru nezasahuje – nebo se cache prostě zahodí. Tak jako tak, cache nakonec vyřešila dlouhé čekání uživatele na nějaké informace a i moje čekání na načtení seznamu uživatelů a jejich činnosti.

Nakonec mě Redis zaujal natolik, že jsem se rozhodl ho použít i na další věci než jen cache a už pro něj upravuji i fakturační systém, kde bude udržovat informace o jednotlivých platbách a odečtech. Těch bude časem víc a víc a bude potřeba je číst všechny. Proto mě začal zajímat výkon, pro jehož měření nám vývojový tým napsal malou utilitku redis-benchmark. Ta na mém desktopovém Athlonu X2 (2100MHz) se 4 GB RAM, vymáčkla z Redisu kolem 17 000 GET požadavků za sekundu. Záleží samozřejmě na mnoha faktorech a s každou pokročilejší funkcí Redis na výkonu ztrácí, ale i díky nim je Redis tím, čím je, takže stačí jen dobře zvolit datovou strukturu.

Replikace

Škálovatelnost dnes slyšíme čím dál víc a u NoSQL databází to není takový problém jako u těch relačních. I proto poráží relační databáze na místech, kde je výkon kritickým požadavkem. Dnes už vývojáři všech databází pomalu doplňují alespoň MASTER-SLAVE replikaci. Ta sice není tak komplexně využitelná jako MULTI-MASTER replikace a la Cassandra, ale stále je to lepší než nic.

Redis podporuje MASTER-SLAVE replikaci s tím, že ze všech SLAVE instancí lze číst, ale zapisovat jen na MASTER. V jedné z příštích verzí by se měla objevit i read-only konfigurační volba, která v takovémto případě zabrání i pokusům o zápis.

Append Only File

Když se zamyslíte nad tím, jak Redis funguje, asi se trochu zpotíte, protože když změníte trochu konfiguraci a potřebujete Redis restartovat, tak neuložená data zmizí (kdy se mají ukládat, se dá nastavit). Tomu pomůže zabránit tzv. Append Only File (AOF), kam se zapisují všechny příkazy, které databázi nějakým způsobem změní. Redis pak je při havárii schopen z tohoto souboru obnovit původní databázi. AOF není součástí souboru s normálními daty, je to další soubor s výchozím názvem appendonly.aof. Data do něj zapsaná jsou v člověkem čitelné formě, takže když si ho vypíšete, uvidíte, co všechno jste měnili.

U AOF si musíte dát pozor na tři věci. Když se rozhodnete ho zapnout za běhu databáze, tedy zapnout konfigurační volbu appendonly a server restartovat. V mém případě to vedlo ke ztrátě všech dat. Naštěstí pomohla záloha.

Druhá věc, na kterou si dejte pozor, je velikost AOF souboru. Když bude množství dat v něm uložených větší než malé, máte k dispozici příkaz BGREWRITEAOF. Ten vytvoří nový AOF, Redis mezi tím ukládá změny do paměti i do starého AOF, a když zápis do nového AOF skončí, jsou do něj přelity nové změny z paměti a nový AOF se přejmenuje na název toho starého. Díky tomuto postupu byste neměli přijít o žádná data. S tím souvisí třetí věc, na kterou si dát pozor.

A to je frekvence zápisu do AOF. Buď můžete zapisovat rovnou, podle OS a nebo každou sekundu. Při zápisech rovnou vývojáři varují, že se může snížit výkon. Když se rozhodnete zápis do souboru nechat na operačním systému, mělo by jít o nejrychlejší variantu, ale při ztrátě napájení nebo jiné katastrofě o data přijdete. Poslední možnost je v konfiguračním souboru reprezentována jako everysec a podle vývojářů jde o volbu s nejlepším poměrem rychlost/bezpeč­nost.

Datové typy

Proč Redis použít nebo nepoužít už máme snad ujasněné a nastal čas si povědět něco o jeho použití. Začneme jeho datovými strukturami, pro programátory to nejdůležitější, protože když je znají, mohou nastartovat svoji fantazii a pustit se do práce. Tady jsou:

  • řetězce
  • seznamy
  • sady
  • seřazené sady
  • hashe (asociativní pole)

Bez popisu by nám těch pět výrazů moc neřeklo, takže retězci se myslí klasické key-value úložiště, tzn. pod jedním klíčem najdeme jeden řetězec. Seznamem je myšleno několik hodnot, nad kterými je možné volat funkce jako přidat na konec (RPUSH), přidat na začátek (LPUSH), získat hodnotu z konce a odebrat ji ze seznamu (RPOP) atd. Sadou se má na mysli neseřazený shluk prvků. Seřazená sada je to samé, jen – jak název napovídá – jde o seřazený shluk prvků. Nakonec nám zbývají hashe, což je prakticky to samé co asociativní pole, a tím se Redis trochu přibližuje dokumentovým databázím.

Nad všemi datovými typy jsou i další funkce, které se mohou hodit a které prakticky definují použití daného datového typu. Chce to trochu fantazie, ale když těchto funkcí dokážete využít, nebudete litovat. Jde třeba o funkce jako inkrementace, dekrementace, trimování prvků seznamu, průnik prvky, sjednocení prvků a mnoho mnoho dalších. Tady by byl podrobnější popis asi zbytečný, spíš se podívejte do velmi dobře zpracované dokumentace.

Protokol

Redis komunikuje s klienty i se svými SLAVE instancemi přes jeden TCP port (výchozí 6379). Komunikace není nějak šifrovaná, takže paranoikové by měli použít VPN nebo SSH tunel. Protokol sám je hodně jednoduchý a samozřejmě je popsán v dokumentaci. Komunikace mezi klientem a Redis serverem není o moc jiná než komunikace programátora s API, prakticky se do požadavku přidá jen počet argumentů a jejich délka.

*<počet argumentů> CR LF
$<počet bytů 1. argumentu> CR LF
<data> CR LF
...
$<počet bytů Ntého arumentu> CR LF
<data> CR LF

V reálné komunikaci to pak vypadá takto:

*3
$3
SET
$5
mykey
$7
myvalue

To znamená, že požadavek má tři argumenty, první argument má tři byty a je v něm SET. Druhý argument má pět bytů a je v něm název klíče mykey. Třetí argument je hodnota uložená pod klíčem myvalue a má sedm bytů. Když se pozorně zadíváte a ještě jednou si catnete AOF, zjistíte, že to je to samé.

První byty

Binding pro Redis najdeme téměř v každém dnes používaném programovacím jazyce, takže když už se rozhodnete ukládat data do Redisu, zde pravděpodobně nenarazíte. Nezbývá tedy než si trochu vštípit použití několika jednoduchými příklady. Nemusíte hned instalovat Redis, abyste si ho vyzkoušeli. Na to vám stačí Try Redis na adrese try.redis-db.com.

Vytvoření několika klíčů s hodnotami a použití inkrementace a dekrementace pak vypadá nějak takto:

> SET k1 hodnota
> SET k2 hodnota2
> SET i 0
> GET k2
"hodnota2"
> INCR i
> GET i
"1"
> DECR i
> GET i
"0" 

A teď si představte, že tohle můžete udělat 2000krát v jedné sekundě na běžném hardwaru.

Závěr

Článek si nekladl za cíl seznámit vás s každým příkladem, na který vám Redis kladně odpoví, ani s jednotlivými konfiguračními direktivami v konfiguračním souboru, ale hlavně ukázat, jak se chová, abyste se mohli rozhodnout, jestli pro něj máte využití, nebo zda se podíváte jinde. Redis umí být dobrým a hlavně bleskově rychlým pomocníkem, ale pokud se k němu zachováte unáhleně, mohli byste narazit. S daty si opravdu pohrává tak nějak ve vzduchu a ani mechanismy na jejich ochranu vám nemusí dát skutečný pocit sucha a bezpečí. Já se rozhodl Redis použít a držím všem ostatním palce.

Odkazy

Komentáře: 8

Přehled komentářů

expert memcachedb
msgre Re: memcachedb
msgre Doplnění odkazů
balki Rozdiel
MilanK Sady?
František Kučera Re: Sady?
amra3 Redis a Grails
Ladislav Thon Re: Redis a Grails
Zdroj: https://www.zdrojak.cz/?p=3341