MS Certificering: AZ-204, deel 3

Ingediend door Dirk Hornstra op 17-aug-2021 23:40

Hoofdstuk 1 (link) en hoofdstuk 2 (link), nu tijd voor het 3e hoofdstuk, ontwikkelen voor opslag van data in Azure. In dit hoofdstuk gaan we een 4-tal opslagmethodes behandelen.

Opslag in storage tables.

Storage tables, hierbij werk je met noSQL. Dus zonder schema sla je de data op in key-value-pairs. Waarbij je on-the-fly de indeling aan kunt passen. En het voordeel is dat het meestal minder kost dan de zelfde ruimte gebruiken met een "traditionele database". Er zijn 2 varianten, Azure Table Storage en Azure Cosmos DB Table. In dit blok wordt de Azure Cosmos DB Table API besproken. Je kunt de calls authenticeren, er kan een grote dataset opgeslagen worden, je kunt OData gebruiken, LINQ query's met WCF Data Services.

Je moet eerst een Storage Account maken. Binnen dat account kun je zoveel tabellen aanmaken als je maar wilt, zolang ze maar een unieke naam hebben, mag alleen uit alfanumerieke karakters bestaan, de naam kan niet beginnen met een cijfer, ze zijn case-insensitieve (dus als je een TABEL123 aanmaakt, kun  je geen tabel123 meer aanmaken).

De tabellen bestaan uit "entities", je kunt deze als een "rij in de tabel" zien. Deze kan 1 MB groot zijn en 252 eigenschappen bevatten om data in op te slaan. Als je een entity aanmaakt, voegt het systeem automatisch deze 3 eigenschappen toe:

  • partition key: hiermee kun je sneller query'-en over een groep entiteiten
  • row key: een unieke waarde binnen een partitie
  • timestamp: aanmaak datum + tijd van de entiteit


De eigenschappen (key-value waarden) zijn wel case-sensitive, een naam kan uit maximaal 255 karakters bestaan en je krijgt het advies om voor het bedenken van een naam de standaarden te volgen: link.

Omdat Table Storage afgeleid is van Azure Storage heb je een aantal authorisatie-mechanismes beschikbaar:

  • shared key authorization: je hebt 2 access-keys, daarvan gebruik je 1 in de authorization-header bij aanroepen. Hierbij kun je bij het volledige Storage Account, blobs, bestanden, queue's en tabellen. Zie het als "het root password" van het storage account.
  • shared access signatures: met een SAS kun je beperken waar je toegang tot krijgt en hoef je geen 'root-access-keys' te delen.


Met SAS kun je de toegang met cliënten delen, je kunt SAS nog als volgt configureren:

  • services: je kunt instellen dat alleen toegang gegeven wordt tot blog, files, queue of tabel(len).
  • resource types: je kunt de toegang instellen tot een service, container of object. Met de Table service kun je instellen dat je een lijst van de tabellen kunt tonen. Zit het op container-level, dan kun je ook tabellen aanmaken of verwijderen. Als het op object-level zit kun je entiteiten in de tabel aanmaken of bijwerken.
  • permissions: hier kun je instellen wat iemand wel of niet mag doen in de geconfigureerde bronnen en services.
  • data expiration: je kunt de SAS beperken tot een bepaalde periode
  • IP adresses: je kunt instellen dat 1 of een range van IP adressen toegang heeft (en de rest dus niet)
  • protocols: je kunt instellen of iemand met HTTPS of met HTTPS en HTTP toegang kan krijgen. alleen HTTP wordt niet ondersteund.


Een SAS is ook nog te onderscheiden in 2 types, Account SAS: toegang tot het volledige Storage Account, Service SAS: toegang tot bepaalde specifieke services in het Storage Account.

Om de data op te vragen, moet je een token toevoegen in de URL. Dit geldt zowel voor een Account SAS als een Service SAS (iets andere parameters). Dat lijkt mij niet super veilig (als iemand die URL heeft kan hij/zij ook bij je data). In het boek wordt gesproken over een Stored Access Policy, daar doe je iets met een identifier en die gebruik je om een token op te bouwen. Dat klinkt als een soort private key.

Je kunt met code de data benaderen. Dat kan met .NET framework, standard, Java, NodeJS, PHP, Python, PowerShell, C++ of een REST API. Als je .NET Standard gaat gebruiken, dan heb je de Azure Cosmos DB .NET SDK nodig. Je gebruikt het nuget-package Microsoft.Azure.Cosmos.Table. Als je .NET Core gebruikt moet je ook Microsoft.Azure.Storage.Common toevoegen.

Als je dit package gebruikt kun je:

  • CloudStorage Account: in je Storage Account je tabellen aanmaken of bewerken.
  • CloudTableClient: hiermee kun je de Table service gebruiken. Als je een table reference hebt kun je met een instantie van een CloudTable class met de tabel werken.
  • CloudTable: representatie van een tabel. Om iets te doen met de entiteiten heb je een TableOperation-object nodig.
  • TableOperation: actie uitvoeren (verwijderen, aanmaken, bijwerken).
  • TableResult: bevat het resultaat van een TableOperation-actie.
  • TableEntity: elk document dat je toevoegt moet een child zijn van een TableEntity class.


De eerder genoemde systeemvelden, partitionkey, rowkey en timestamp, hiervan wordt gezegd dat je ze moet aanleveren. Dus schijnbaar als je het in code doet, moet je dat zelf doen? PartitionKey en Rowkey zijn string-velden, dus 232 verschijnt voor 4. Je kunt deze velden gebruiken om het zoeken te versnellen. Het is ook de enige index. Wil je meer indexen toevoegen, dan moet je over naar Cosmos DB premium storage.

Elke table storage node heeft één of meerdere partities. Als de service zwaar belast wordt, kan er opgeschaald worden naar meerdere nodes. Als je een "atomic action" over een groep van entiteiten wilt doorvoeren, dan kan dat, maar de voorwaarde is dan wel dat ze allemaal dezelfde PartitionKey hebben (Entity Group Transactions, EGT). Als je minder partities hebt kun je dit meer uitvoeren, maar daarbij beperk je de schaalbaarheid. Zo heb je de limiet van 500 entiteiten per seconde, als dat geraakt wordt, wordt er opgeschaald, waardoor er load-balancing komt en het proces dus vertraagd kan worden.

Om te zoeken heb je een aantal query types:

  • Point Query: je zoekt zelf op PartitionKey en RowKey, krijgt 1 (of geen) resultaat.
  • Range Query: je zoekt op PartitionKey en geeft de RowKey een range, waardoor je meerdere resultaten kunt krijgen.
  • Partition Scan: je zoekt op PartitionKey en nog een ander veld.
  • Table Scan: je zoekt niet op PartitionKey, de hele tabel moet gescand worden.

In termen van snelheid is Point Query de snelste, daarna Range Query, etc.

Je hebt verschillende patronen om je tabellen in te richten;

  • Intra-partition secondary index pattern: snel zoeken mogelijk maken door kopieën van entiteiten te maken en verschillende RowKeys te geven om zo verschillende sorteringen mogelijk te maken.
  • Inter-partition secondary index pattern: meerdere kopieën van entiteiten in verschillende partities of andere tabellen om met afwijkende RowKeys-waardes de sortering te beïnvloeden.
  • Eventually consistent transactions patterns: door Azure queue's te gebruiken kun je de beperking om alleen binnen een eigen partitie een transactie door te voeren omzeilen.
  • Index entities pattern: je gebruikt externe opslag, bijvoorbeeld een blob, waarin je lijsten van indexen bijhoudt op basis van niet unieke eigenschappen. Bijvoorbeeld werknemers van een bedrijf, PartitionKey is de afdelingnaam, RowKey is de employee ID. Je kunt een lijst "Smith" maken van alle medewerkers met achternaam Smith.
  • Denormalization pattern: omdat het noSQL is kun je gedetailleerde informatie opslaan bij dezelfde entiteit, waar je bij een relationele database andere tabellen zou gebruiken.
  • Data serie pattern: als je in een entiteit de temperatuur voor een dag bij houdt (wordt elk uur opgeslagen), dan zou je per dag 24 requests moeten uitvoeren. Je maakt een nieuwe entiteit aan die alle waardes per dag opslaat, dus je hoeft maar 1 request uit te voeren.
  • Compound key pattern: je gebruikt de waardes van rowkey van 2 verschillende entiteiten om een nieuwe entiteit te maken die deze 2 combineert.
  • Log tail pattern: standaard worden waardes gesorteerd op partitionkey en dan rowkey. Dit pattern geeft n entiteiten terug die het meest recent aangemaakt zijn op basis van rowkey.
  • High volume delete pattern: als je heel veel entiteiten moet verwijderen, kun je die het beste naar een andere tabel verplaatsen. Je hoeft daarna alleen die tabel te verwijderen.
  • Wide entities pattern: als je entiteiten aan moet maken die meer dan 255 eigenschappen hebben, dan moet je logische entiteiten splitsen naar meerdere fysieke entiteiten.
  • Large entities pattern: als je entiteiten op moet slaan die meer dan 1 MB groot zijn, dan kun je de BLOB opslagservice gebruiken om daar de extra informatie in op de slaan en een pointer naar die blob in je entiteit op te slaan.

Je kunt hier meer lezen over de design patterns: link.

Opslaan van data met Cosmos DB.

Cosmos DB is een premium oplossing, schaalbaar, altijd online. Door het aanklikken van een knop kun je in 1x een nieuwe regio aan je database toevoegen.

Je hebt verschillende opslag-methoden, daarbij heb je ook verschillene API's beschikbaar;

  • SQL: je kunt JSON query-en met SQL, onder de motorkap wordt dat omgezet naar javascript. De datastructuur is gericht op documenten.
  • Table: dit is de uitgebreide versie van Azure Table Storage, hier kun je wel je eigen indexen toevoegen. Ook hier gebaseerd op documenten.
  • Cassandra: product van Apache (database), moet je veel beheer doen bij Cassandra, dat hoeft hier niet. Cassandra is een kolom-gebaseerde database die informatie opslaat met key-value waardes.
  • MongoDB: noSQL database. Cosmos DB implementeert het protocol dat MongoDB ook gebruikt, voor een 3.2 client driver is dus onzichtbaar dat er met MongoDB of Cosmos gecommuniceerd wordt.
  • Gremlin: gebaseerd op Gremlin of Apache TinkerPop graph traversel taal worden zaken met "graven" opgeslagen. Je hebt geen entiteiten maar:
  1. Vertices: een vertext zou je kunnen zien als een entiteit, dus een persoon, device, event.
  2. Edges: dit zijn de relaties tussen de vertices, persoon A kent persoon B die persoon C kent, etc.  Persoon A bezit device X en gaat naar Event M.
  3. Properties: de attributen die je toewijst aan een vertice of edge.


Als je een account maakt moet je 1 van deze API's kiezen. Je kunt er maar 1 kiezen en je kunt deze niet meer aanpassen.

Als je met Cosmos DB wilt testen, kun je eens kijken naar de emulator: link. Meer informatie over SQL-query's kun je hier vinden: link. Een voorbeeld van Gremlin staat hier: link en Cassandra staat hier: link.

Voor goede performance e.d. verdeelt Cosmos je data over partities. Je hebt een logische partitie: een Cosmos DB container wordt in kleinere delen onderverdeeld. Fysieke partitie: dit zijn replica's van jouw data die fysiek op de servers opgeslagen worden. Een logische partitie heeft een limiet van 10 GB. Als je meer ruimte nodig hebt, kun je zorgen dat je container over meerdere partities verdeeld wordt. Cosmos DB moet dan wel weten hoe dat moet. Daar komt de partition key om de hoek kijken. Je kunt die instellen op een veld, die dan immutable wordt. De keuze is belangrijk, zet je deze op een naam, dan zijn er tig mogelijkheden en krijg je ook tig partities: waarschijnlijk teveel. Zet je die op een veld waarbij heel veel dubbele waardes voorkomen, dan krijg je waarschijnlijk een hele volle partitie, ook niet de bedoeling. Hoe partitionering werkt, dat kun je in deze video zien met GOOD OLD Scott Hanselman!: link.

Met Cosmos DB kun je makkelijk je data repliceren naar andere regio's. Addertje onder het gras is de data-consistentie, kijken we hier naar de live-data of is dit nog "oude replicatie data"? Het consistency level kun je instellen. Daar heb je deze opties:

  • Strong: je kijkt altijd naar de meest recente data. Maar dit kan flinke vertragingen opleveren en bij zaken die fout gaan ervoor zorgen dat data niet optimaal op te vragen is.
  • Bounded Staleness: de lees-acties zijn consistent op basis van een bepaalde "lag". Dat kan zijn dat je altijd binnen een x aantal recente versies zit (dus is die waarde 3, dan kijk je naar huidige data, data van een vorige versie, van daarvoor of van daarvoor, maar zeker niet eerder) of binnen een tijdsinterval (misschien niet recent, maar maximaal 15 minuten oud).
  • Session: beste balans tussen consistentie en performance.
  • Consistent Prefix: je kunt de data lezen in de volgorde dat je het weggeschreven hebt, maar niet altijd alle data. Dus als je A,B,C weggeschreven hebt, dan zou je kunnen lezen: "A", "A, B", "A,B,C", maar nooit "A,C" of "B,A,C".
  • Eventual: er zijn geen schrijf-acties. Er is geen garantie dat de data in de juiste volgorde binnen komt.
     

Als je denkt, ik wil zelf een consistency level maken, hier is meer informatie: link. En een duidelijke uitleg van de zaken hierboven is hier te lezen: link.

Als je SQL of Table API gebruikt, dan zijn dit de adviezen:

  • session consistancy is het meest aan te raden.
  • als je "strong" overweegt, kies dan voor bounded staleness omdat het lineaire acties garandeert met een instelbare vertraging.
  • de hoogste "strong" en de laagste, "eventual" zijn opties waarbij je heel zeker moet zijn dat ze dé oplossing voor jou zijn.


Cassandra en MongoDB gebruiken hun eigen consistentie, dus die regelt Cosmos DB zelf.

Opslaan van data met een relationele database.

Azure biedt de Azure SQL Database als een "database as a service".

  • Single database: 1 database, vergelijkbaar met contained databases in SQL Server 2017
  • Elastic pool: meerdere databases, niet bekend of ze zwaar belast worden of niet.
  • Managed instance: vergelijkbaar met SQL server  op een Azure virtual machine, maar je hoeft hier niet een VM te provisionen en onderhouden. Vaak gebruikt als een "on premise" SQL server instantie in de cloud wordt gezet.

In dit overzicht kun je de opties vergelijken: link.

Er zijn 2 aankoopmogelijkheden:

  • DTU-gebaseerd: resources worden gegroepeerd naar basic, standard, premium. Database Transaction Unit groep van opslag, databases, IO-verkeer. Kan niet bij een managed instance gebruikt worden.
  • vCore-gebaseerd: je kunt de hardware kiezen, prijsmodel geeft de keuzes general purpose of business critical. Bij een single database kun je ook een extra service tier, hyperscale toevoegen. Je betaalt hier voor:
  1. Compute: aantal vCores, hoeveelheid geheugen, hardware
  2. Data: hoeveelheid ruimte voor opslag data en logs
  3. Backup storage: configureer de Read Access Geo-Redundant Storage


Als je een enkele database of elastic pool hebt met meer dan 300 DTU, dan is het verstandiger om over te stappen naar vCore. Het kostenplaatje e.d. kun je hier bekijken: link.

SQL Databases staan naar buiten "standaard dicht", dus je moet in de Azure Firewall je eigen IP toevoegen om toegang te krijgen. De periode dat back-ups bewaard worden ligt tussen de 7 en 35 dagen (afhankelijk van hoeveel geld je betaalt). De exclusieve long-term om het 10 jaar op te slaan, daar kun je hier meer informatie over lezen: link. En in dit artikel kun je lezen hoe je een back-up terug kunt zetten: link.

Meer informatie over het instellen van limieten bij elastic pools, dat kun je hier vinden, de DTU-info: link en de vCore-info: link. Je kunt met en SQL-user authenticeren, maar je kunt ook Azure Active Directory gebruiken (net zoals je met een SQL Server installatie op je eigen pc kunt instellen dat je met je Windows-credentials connectie kunt maken). Meer info: hier.

Opslaan van data met "blob storage".

De eerdere oplossing zijn "prijzig". Voor data die niet rechtstreeks voldoet aan SQL en noSQL heb je de BLOB-storage. Afbeeldingen, video's, documenten.

Met het azCopy commando kun je blogs van het ene Storage Account naar de andere kopiëren. Of naar een andere container.

Je kunt extra informatie toevoegen aan een blob. Dat doe je met System properties: de storage service voegt dit automatisch toe, sommige eigenschappen zijn aan te passen, andere niet. Sommige eigenschappen komen overeen met headers, kijk ook hier: link. User-defined metadata: je kunt key-value pairs toevoegen.

Als meerdere personen een blob aan willen passen, dan kun je problemen krijgen. Daarom wordt er gewerkt met een lease. Hiermee krijg je exclusieve schrijf- en verwijder-toegang. Een lease heeft 5 statussen:

  • available: unlocked, je kunt een nieuwe lease krijgen.
  • leased: in bezit van iemand anders. als je de ID van de lease hebt, kun je deze vernieuwen, daarnaast kun je release, change, renew, break op de lease uitvoeren.
  • expired: verlopen, als je deze lease had kun je die acquire, renew, release, break.
  • breaking: je hebt 'm gebroken, lease is nog een x periode actief. je kunt een release of break doen.
  • broken: break periode is verlopen. acquire, release en break kun je uitvoeren. als er een netwerk hick-up oid geweest is, kun je niets met de blob en moet je de lease breken.


Informatie over "lease a blob": link en over "lease container": link.

Er zijn verschillende toegangslevels. Als een document bijvoorbeeld maar 1x per jaar opgevraagd wordt, dan kan deze beter op een "goedkoop deel" gezet worden, het opvragen mag wel wat langer duren.

Hot: data die je regelmatig opvraagt. De standaard bij aanmaken van een Storage Account.

Cool: minder vaak opgevraagde data, ten minste 30 dagen opgeslagen. Lagere opslagkosten (en SLA), hogere toegangskosten.

Achive: nog minder opgevraagd en minimaal 180 dagen opgeslagen. Offline opslag, laagste opslagkosten, maar hoge toegangskosten.

Storage Tiering kan alleen met een GPv2 Storage Account.

Je kunt met policies zorgen dat zaken overgezet worden. Een lifecycle management policy is een JSON document waarin meerdere regels staan de je wilt toepassen op de verschillende containers en/of blob-types. Deze bestaan uit:

  • Filter set: limiteert de acties alleen tot een groep die aan het filter voldoet.
  • Action set: hierin staat de actie die uitgevoerd wordt op het resultaat van de filter set.


Uitleg en voorbeelden zijn hier te bekijken: link.