Základy Amazon SimpleDB

Asi nejznámějším cloudem je Amazon AWS, který poskytuje širokou škálu služeb – od virtuálních strojů (EC2) a úložiště (S3) až po platební bránu či „webové rozhraní k lidské práci“ (Mechanical Turk). Jednou ze služeb je i NoSQL databáze, nazvaná prostě SimpleDB. V tomto článku se budeme věnovat právě jí.

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

SimpleDB je součást cloudu AWS, ale při jeho použití nejsme nijak vázáni nutností využít dalších služeb, lze tedy používat pouze SimpleDB, a to i pro služby, které fungují na jiných serverech (je ale důležité si uvědomit, že data, která jsou přenesena v rámci AWS, jsou výrazně levnější).

Databáze SimpleDB je zástupcem tzv. Key-Value databází, tedy databází, kde jsou data ukládána nikoli do tabulek ve vysoce normální formě, ale naopak jako poměrně nestrukturované shluky dat s plochou strukturou. Pro tyto databáze, spolu s dokumentovými, objektovými a dalšími nerelačními databázemi, se vžilo označení NoSQL. NoSQL databáze vyvolávají obrovské vášně (i v diskusích zde na Zdrojáku), kdy některým zastáncům relačního modelu připadá, že jsou NoSQL prezentovány jako univerzální všelék a spasení (což někdy může tak působit), a další zkrátka nejsou ochotni přijmout jiné paradigma, navíc takové, které z podstaty neobsahuje silný řád.

Na úvod je tedy nezbytné poznamenat, že NoSQL, mezi něž SimpleDB patří, nejsou ani všelék, ani univerzální nástroj. Mají své místo, mají své výhody i nevýhody, a je potřeba k nim přistupovat jako ke každé jiné technologii: Nepoužívat je bezhlavě, ale s rozmyslem. 

Výhodou NoSQL databází je obvykle snadná škálovatelnost a vysoká rychlost, daná především denormalizovaným tvarem dat, redundantním ukládáním a minimální „inteligencí“ takových databází (zapomeňte na constraints, triggery, uložené procedury, JOINy a další věci, které jsou běžné – a nutné – v SQL světě). Daní, kterou je za to nutné zaplatit, je přesun veškeré logiky na stranu serveru, ztráta ACID, nutnost ošetřit případné nekonzistence na straně aplikace…

NoSQL databáze tak zkrátka nejsou databází pro každou aplikaci. Svůj smysl mají na webech, kde se pracuje s obrovským počtem záznamů a s velkou zátěží (na NoSQL databázi, konkrétně Cassandra, například přešel Digg, kde jsou uváděny počty pageviews v řádu půl miliardy měsíčně). Tam se naplno projeví výhody jednoduché škálovatelnosti, kdy náklady na HW rostou s počtem záznamů pomaleji než u klasického SQL stroje. Na druhou stranu není nikde psáno, že byste nemohli použít NoSQL pro pohon svého blogu v PHP – jen to bude pravděpodobně overkill, kdy nevýhody takového řešení převáží nad výhodami, a to především co do snadnosti udržení takové aplikace či ceny.

Architektura SimpleDB

Databáze SimpleDB používá jednoduchou strukturu dat: Na nejvyšší úrovni je uživatelský účet (account). V každém účtu se data dělí do domén (domains). Do domén jsou ukládány položky (items) – každá položka má v rámci domény unikátní identifikátor (name). Každá položka může mít až 256 atributů (attributes). Atributy pak nabývají určité hodnoty (value).

Amazon pro výklad používá příměru k tabulce z tabulkového procesoru (tabulkou zde je míněno to, co známe z Excelu, nikoli databázovou tabulkou): Doména odpovídá listu dokumentu, položky jsou řádky, atributy sloupce a hodnoty pak konkrétní políčka. Pokud bychom chtěli sáhnout k analogii ze světa RDBMS, tak doména bude zhruba odpovídat databázové tabulce, položka záznamu, atributy pak sloupcům. Ovšem je třeba si uvědomit, že analogie s RDBMS je velmi volná, a to především z jednoho důvodu: Struktura dat není pevně daná!

V praxi to znamená, že libovolný záznam může mít libovolné atributy. Je zcela na uživateli, jaké atributy záznamu vyplní; není svázán žádnou strukturou, žádnými „povinnými položkami“, ničím podobným. (Tato svoboda ale může snadno v rukou nezkušeného či neukázněného vývojáře napáchat neskutečné škody.) Srovnat by se to dalo snad jen s RDB tabulkou, která má povinný primární klíč ID, ostatní sloupce jsou nepovinné, a navíc vznikají ve chvíli, kdy jsou použity při zápisu do nějaké položky, transparentně a na pozadí (není je tedy nutno předem nijak specifikovat).

Omezení

Pokud se vám v tuto chvíli dělá mdlo z „neřádu“, vydržte, bude ještě hůř. Hodnoty ukládané do SDB totiž nemají žádný typ. Lépe řečeno: Jsou to řetězce. Pokud chceme pracovat s čísly (například porovnávat), musíme počítat s tím, že SimpleDB nezná typ číslo a všechna porovnání bere jako porovnání řetězců. Řeší se to tak, že čísla jsou do SimpleDB ukládána v normalizovaném tvaru, tedy doplněné nulami zleva, a pokud mají být i záporná, tak jsou předem převedena na kladná přičtením offsetu. Ovšem tuto normalizaci nedělá databáze – musí na ni myslet programátor aplikace, a musí na ni myslet včas.

Na tomto místě je vhodné zmínit limity SimpleDB. Jména atributů i hodnoty mohou mít nejvýše 1024 bajtů (obrázek tedy do databáze jen tak neuložíte, dokonce ani článek na blog). Stejně tak smí mít 1024 znaků jméno položky (ID). Každá položka může mít 256 dvojic atribut – hodnota. V jedné doméně může být použita maximálně jedna miliarda atributů, doména má maximální velikost 10GB a v jednom účtu smí být sto domén. SimpleDB tedy znamená opravdu „jednoduchá“ – i když relativně velká.

Omezení velikosti záznamů, které bude pro switchery ze světa RDBMS asi nejcitelnější, vychází z filosofie AWS, kde je vše podřízeno škálovatelnosti. Jsou proto oddělena data od aplikace, a jsou zde oddělena i data od metadat – pro data je určeno S3, pro metadata právě SimpleDB. Pokud bychom psali tedy výše zmíněný blogovací nástroj nad AWS technologiemi, tak bychom museli ukládat texty článků a komentářů do souborů v S3 a informace o nich do SDB. (Já vám říkal, že to je nesmysl, a že to s **SQL půjde mnohem líp!)

Konzistence

Dalším omezením, které je třeba zmínit, je konzistence. Veškeré domény jsou ukládány, kvůli vysokým nárokům na trvanlivost dat, odolnost proti výpadkům a rychlost přístupu, v několika kopiích. Při operacích zápisu se změny propagují do ostatních kopií, a tato propagace nějakou dobu trvá. Amazon uvádí, že v běžných případech jsou data změněna ve všech kopiích zhruba do jedné sekundy, ale zároveň dodává, že v případě epizodické vysoké zátěže může tato doba narůst.  Není řečeno na jak velkou dobu, ale je garantováno, že nakonec jsou data zapsána.

Problém nastane, jak je jistě patrné, v případě, kdy jeden proces čte položku, kterou jiný proces právě změnil. Bude záležet na tom, zda čte z kopie, kde je již změna uložena, nebo z nějaké, kde ještě není. SimpleDB přiděluje kopie domén k požadavkům na základě momentálního vytížení, tudíž nelze nijak ovlivnit, k jaké kopii se právě přistupuje – navenek se celý cluster domén tváří jako jeden celek, jen s tím drobným zádrhelem, že v jeden okamžik může dvěma procesům vrátit na stejný požadavek zcela rozdílná data.

SimpleDB proto nabízí dva přístupy ke konzistenci dat pro čtecí operace: Konzistentní čtení a Časem konzistentní čtení (Consistent readEventually consistent read). Běžně se používá „časem konzistentní“ operace – tedy SDB vrátí data z té kopie, co plánovač právě přiřadí, i s rizikem toho, že mohla být mezitím změněna. Tento přístup je nejrychlejší – je minimální čekací doba na odpověď i největší průměrná přenosová rychlost.

V případech, kdy na konzistenci opravdu záleží, lze specifikovat konzistentní čtení (pomocí parametru ConsistentRead=true) – v takovém případě je zaručeno, že data reflektují všechny předcházející zápisové operace, které skončily úspěšně. Nevýhody jsou zjevné: Je možné, že budete na data čekat, a přenos bude tedy i pomalejší.

Podrobněji se otázkami konzistence a přístupu konkurenčních procesů zabývá Developer Guide – Concurrent Applications.

Operace se SimpleDB

K SimpleDB lze přistupovat prostřednictvím dvou API – REST a SOAP. Tato API nabízejí několik základních operací, které si teď ve stručnosti představíme – ostatně už jejich jména jsou samovysvětlující:

Možná vás zarazí, že SDB nemá různé operace pro vytvoření položky a její změnu. Vše podstatné se děje pomocí dvou operací, totiž PutAttributes (resp. BatchPutAttributes) a DeleteAttributes.

PutAttributes má jako parametr jméno položky (jak jsme si řekli, je unikátní v rámci domény) a seznam atributů a jejich hodnot. Pokud položka s takovým jménem neexistuje, je vytvořena a jsou do ní zapsány atributy. Pokud položka existuje, je změněna. Zadané hodnoty existujících atributů jsou přitom přepsány, neexistující atributy jsou nově vytvořeny. Tato operace tak v sobě zahrnuje INSERT, MODIFY i ALTER TABLE. DeleteAttributes smaže atributy z položky. Pokud v položce už žádný atribut nezůstane, je odstraněna.

Obě tyto operace, jak Put, tak Delete, mohou být podmíněny – např. tím, že jsou provedeny jen pokud hodnota nějakého atributu je rovna zadané hodnotě apod.

Pro získání dat jsou používány dvě operace, a to GetAttributes a Select. GetAttributes očekává jméno položky a vrátí všechny přiřazené atributy a jejich hodnoty (popř. hodnotu jednoho specifikovaného atributu).

Velmi silná je operace Select, která bude lidem, znalým SQL, připadat konečně povědomá. Umožňuje totiž vyhledávat data podle zadaných podmínek a vracet je. Syntaxí je velmi podobná dotazu SELECT ze SQL. Ve zkratce vypadá takto:

select output_list
from domain_name
[where expression]

[sort_instructions]

[limit limit]

V podmínkách lze použít některé operátory, známé ze SQL, takže dotazy mohou vypadat třeba takto:

select * from mydomain where Title = 'SimpleDB'
select * from mydomain where Year > '1985'
select * from mydomain where Rating like '****%'
select * from mydomain where (Year > '1950' and Year < '1960') or Year like '193%' or Year = '2007'

SimpleDB umožňuje v operaci Select přistupovat k hodnotě atributu jako k vícenásobné hodnotě, ale podrobnosti by přesahovaly rámec tohoto článku. Zájemce proto odkazuji na dokumentaci.

Funkce Select pracuje nad indexem, který si SimpleDB pro data vytváří. Vytváření tohoto indexu je transparentní, probíhá na pozadí a uživatel jej nemá možnost ovlivnit. 

Praktické ukázky práce, stejně jako popis REST API, si ale necháme až do dalších článků.

Poznámky

Alternativou k SimpleDB je open source databáze M/DB, která je co do API a chování totožná se SimpleDB. Lze tedy při vývoji použít právě lokálně nainstalovanou M/DB a odladit aplikaci proti ní – ušetříte tím jednak prostředky, jednak se tím vyhnete vendor lock-inu: Svou aplikaci můžete z AWS přenést jinam bez výraznějšího zásahu do databázové vrstvy (je potřeba změnit jen endpoint).

Základním místem, kde se SimpleDB začít, je (samosebou) přihlášení k SimpleDB. Pokud už přístupové údaje máte, je vhodné začít dokumentací, konkrétně SimpleDB Developer Guide a Getting Started Guide. Vhod může přijít i ukázková knihovna (Java, C#, Perl, PHP a VB.NET) – na rovinu řečeno není verze pro PHP moc hezká a bude lepší se porozhlédnout po nějaké jiné, popř. si napsat vlastní (jak na to si ukážeme příště). Knihovny pro ostatní jazyky jsem nezkoumal.

Příště se budeme věnovat podrobněji REST API a ukážeme si, jak provádět základní operace přes toto rozhraní.

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Komentáře: 5

Přehled komentářů

okbob Škálovatelnost NoSQL db
Martin Malý Re: Škálovatelnost NoSQL db
okbob Re: Škálovatelnost NoSQL db
radim.baca Re: Škálovatelnost NoSQL db
Tar Eventually
Zdroj: https://www.zdrojak.cz/?p=3201