Detailní rozbor nákladů na storage službu Windows Azure

Azure Storage je jednou ze služeb cloud platformy, která je zcela nová, nemá v tuto chvíli odpovídající technologii na lokálních serverech nebo PC a její cena se ze 100% odvíjí z přímé konzumace. Na rozdíl od jiných cloud služeb, jako jsou Windows Azure Compute nebo SQL Azure, se její cena výhradně počítá podle používání. Služba může být tedy zapnuta 24x7x365 a pokud ji nepoužívám, nic neplatím. To je jednodušší část mého dnešního blog postu. Podívejme se nyní, jak přesně se bude vypadat v případě, kdy službu používat budu.

Nejdříve si dovolím zopakovat informace, které jsou povětšinou již dobře známy:

  • Cena 1 GB dat v Azure Storage je 0.15 USD/měsíc
  • Cena za 10 tisíc transakcí nad Azure Storage je 0.01 USD/měsíc
  • Cena za 1 GB dat přenesený do datového centra z internetu je 0.10 USD/měsíc (Severní Amerika a Evropa), 0.30 USD/měsíc (Asie)
  • Cena za 1 GB dat přenesený z datového centra do internetu je 0.15 USD/měsíc (Severní Amerika a Evropa), 0.45 USD/měsíc (Asie)

Touto informací mnoho webů a blogů končí. Tento článek teprve začíná a tak se podívejme, co výše uvedené body ve skutečnosti znamenají. Následující text je rozdělen do dvou částí:

Měření a odhad využité kapacity storage

Výsledná cena za uložená data je počítána jako průměrná hodnota z kapacity, která je měřena minimálně jedenkrát za den. Naměřené hodnoty se zprůměrují a výsledná kapacita se objeví na měsíčním účtu. Ilustrujme si tuto část na praktickém příkladu. Řekněme, že jeden den uložím do Storage 300 GB dat a po zbytek měsíce všechna data smažu. Výsledná faktura bude tedy obsahovat 10 GB (předpokládám 30 dní/měsíc).

Když se řekne 1GB dat uložených službou, kolik to ve skutečnosti znamená skutečných informací a jaký je případný overhead jednotlivých typů úložišť (tabulka, blob, fronta)? Rozeberme si tedy každý typ úložiště a definujme přesně na nejnižší úrovni ukládaný obsah. V níže uvedených vzorcích se objevuje funkce Len(x), která vrací počet uložených znaků. Dále pak je nutné si uvědomit, že znaky jsou v Azure často ukládány pomocí Unicode a prakticky tedy zabírají 2 bajty.

Blob storage

Bloby jsou organizovány do tzv. Kontejnerů. Každý konejner může obsahovat více blobů. V následujících třech tabulkách vidíme, kolik budou zabírat informace o kontejneru samotném a následně bloby samotné. Bloby jsou navíc uvedeny ve dvou variantách – page blob a block blob.

Definic jednoho blob kontejneru

Vysvětlení

48 bajtů +

Systémové informace ke každému containeru, které obsahují Last Modified Time, Permissions, Public Settings a systémová metadata.

Len( JménoKontejneru) * 2 bajty +

Jméno kontejneru v Unicode

For-Each Metadata[3 bajty + Len(JménoMetadata) + Len(Hodnota)] +

Metadata připojená ke kontejneru, uložená v ASCII

For-Each Signed Identifier[512 bytes]

Tato položka se skládá ze signed identifier jména, start time, expiry time a povolení.

 

Položka jednoho Block Blobu

Vysvětlení

124 bajtů + Len(JmenoBlobu) * 2 bajty+

124 bajtů obsahuje Last Modified Time, Size, Cache-Control, Content-Type, Content-Language, Content-Encoding, Content-MD5, Permissions, Snapshot information, Lease a some systémová metadata. Jméno uloženo v Unicode.

For-Each Metadata[3 bajty + Len(JmenoMetadat) + Len(Hodnota)] +

Metadata připojená k blobu uložena v ASCII.

8 bajtů + počet committed a uncommitted bloků * Block ID Size v bajtech +

Block blob je rozdělen na sérii bloků. Zde jsou informace o jednotlivých blocích. Uncommitted bloky jsou automaticky po týdnu smazány, pokud neproběhne commit.

SizeInBytes( data committed bloků) +

Data v bajtech

SizeInBytes(data uncommitted bloků)

Data v bajtech

 

Položka jednoho Page Blobu

Vysvětlení

124 bajtů + Len(JmenoBlobu) * 2 bajty +

Stejné jako Block Blobu.

For-Each Metadata[3 bajty + Len(JmenoMetadat) + Len(Value)] +

Stejné jako Block Blobu.

Počet samostatných rozsahů stránek s daty * 12 bajtů +

Toto je číslo, které získáte při volání metody GetPageRanges.

SizeInBytes(data v jedinečně uložených stránkách)

Stejné jako Block Blobu.

Table storage

Tady ve srovnání s Blobem situace o něco snadnější. Samotný záznam o tabulce je velký:

12 bajtů + Len(JmenoTabulky) * 2 bajty

Každá entita tabulky má následně toto datové schéma \

Jedna entita tabulky

Vysvětlení

4 bajty +

Systémové informace - Timestamp, systémová metadata

Len (PartitionKey + RowKey) * 2 bajty +

Partition a Row klíče jsou ukládány jako Unicode znaky

For-Each Property(8 bajty + Len(JmenoProperty) * 2 bajty + Sizeof(.Net Property Type))

Každá property (sloupec) má navíc 8 bajtů, jméno uložené v Unicode plus samostatná hodnota daná jedním z předdefinovaných typů

Do tabulky je jeden z následujících typů. Pak Sizeof(.Net Property Type) nabývat hodnot:

  • String – počet znaků* 2 bajty + 4 bajty pro délku řetězce
  • DateTime – 8 bajtů
  • GUID – 16 bajtů
  • Double – 8 bajtů
  • Int – 4 bajty
  • INT64 – 8 bajtů
  • Bool – 1 bajt
  • Binary – sizeof(hodnoty) v bajtech+ 4 bajty pro délku binárního pole

Queue storage

Samotný objekt fronty zabírá následující délku:

Definice jedné fronty

Vysvětlení

24 bajtů +

Systémové informace obsahující Last Modified Timea a systémová metadata

Len(JmenoFronty) * 2 +

Jméno fronty v Unicode

For-Each Metadata(4 bajty + Len(Jmeno) * 2 bajty + Len(hodnota) * 2 bajty)

Každá fronta může mít připojeny metadata. Každá položka má Unicode jméno a hodnotu.

Do front jsou umísťovány jednotlivé zprávy. Ty mají vedle samotných dat ještě provizi v délce 12 bajtů pro systémové informace (Invisibility Time, Creation Time, Dequeue Count, Message ID a systémová metadata).

12 bytes + Len(Message)

Co je to transakce a jak se počítá

Operace nad Azure Storage jsou prováděna před REST volání, případně přes objektová rozhraní, jako je třeba LINQ, které interně využívá REST metody. Pokud jde o transakce, pak platí, že 1 REST volání = 1 transakce. Vedle jednoduchých operací typu „vrať položku z tabulky“, které jsou počítány jako jedna transakce, mohou nastat i složitější případy:

  1. Na základě operace je vrácen tzv. Continuation Token, který signalizuje, že pro načtení/uložení zvoleného počtu dat, je nutné provést několik dalších REST volání. Pak se každé další volání počítá jako samostatná transakce.
  2. Sadu po sobě jdoucích operací (Insert, Update, Delete) je možné sloučit do jedné dávky. Případně lze najednou provést dávkovou operaci nad frontou. Taková to dávková operace je počítána jako jedna transakce.
    Dále je nutné si dát pozor na operace, které na první pohled mohou vypadat tak, že generují jednu transakci, ale ve skutečnosti jich může být více. Konkrétně jde o následující:
  3. Upload velkých blobů. Pokud je blob větší než 32 MB, upload je rozdělen do několika volání pro 4 MB a pak vše spojí v jeden společným committem. Každá REST operace o velikosti 4MB se počítá jako jedna transakce. Na závěr se přidá jedena transkace na finální commit.
  4. Dotazy do tabuly. Pokud výsledek dotazu do tabulky vrátí více řádků, pak je využíván continuation token, jak je popsáno výše, a je započítáno více transakcí.
  5. Uložení dat do tabulky. Pokud zapisujeme data do jedné partice tabulky, můžeme je sdružit do jedné batch transakce, která může mít max. 100 separátních operací. Pokud děláme operaci nad více particemi nebo operace nejsou sdruženy do jedné batch operace, použije se pro každou operaci jedno REST volání a započítá jedna transakce.

Příklady jsou uvedeny v mém dřívějším postu.

Jsou také situace, kdy není transakce započítána. Je jich opět docela hodně. Pokud se transakce nezapočítá, není započítána ani případná kapacita, která byla nutná pro přenesení dat. Zde je seznam situací, kdy se transakce a přenosy nepočítají:

  • Pre-Authentication Failure – chyba, která nastane díky špatně formátované http hlavičce, špatnému URL apod.
  • Authentication Failure – volajícímu se nepodaří autentikovat.
  • Quota Permission Failure – standardně je omezené na 100 TB na účet. Pokud jde přesáhneme tuto kapacitu, lze data pouze číst a mazat. Ostatní operace jsou odepřeny.
  • Incorrect Shared Access Signature (SAS) HTTP Verb/Permission – chyba nastane tedy, pokud je uživatel autorizován, ale je vyžadována operace, která není povolena. Např. zápis, když je povolenou pouze čtení.
  • Anonymous Request Failures – chybné operace při anonymním přístupu.
  • Unexpected Timeouts – operace z důvodu své délky trvání vyprší. Mohou to být např. složité dotazy nad neindexovanými vlastnostmi.

Na závěr musím také uvést případy, kdy jsou transakce započítány, byť z nich nemáme žádný užitek. Těmto situacím bychom se měli samozřejmě vyvarovat, pokud je možné.

Transakční chyby, které vznikají např. snahou smazat objekt, jenž již neexistuje nebo naopak vytvoření objektu, který již existuje. Případy mohou lehce vzniknout, pokud zpracováváme informace paralelně bez odpovídající logiky. Dále to mohou být podmíněné operace nad ETagem, autorizované operace na kontejnery a tabulkami, které neexistují apod. Další skupinu tvoří transakce, které nejsou provedeny z důvody throttlingu nad jednou tabulkovou particí. Pokud taková situace nastane, je nutné tabulku rozdělit do více particí, pomocí jiného partition key. Viz tento blog. Poslední situací je dosažení transakčního timeoutu. Ten si můžete nastavit kratší než je garantovaný v SLA. Pokud jej nastavíte a operace je delší, transakce se počítá.