Amazon DynamoDB ist der aktuelle NoSQL Service der Amazon Web Services. Es handelt sich dabei um eine verwaltete, skalierbare und bei Bedarf nutzbare Datenbank inkl. bereitgestellten Durchsatz. Der Bereitgestellte Durchsatz ermittelt vorab die Anforderungen für den Lese-und Schreib-Durchsatz, auf deren Basis die Kosten berechnet werden.
Dieses Tutorial von cloudstory.in richtet sich an .NET Entwickler, die mit Amazon DynamoDB starten möchten. Es zeigt, wie eine Tabelle erstellt und darauf Operationen ausgeführt werden. Amazon DynamoDB bietet für .NET-Entwickler dazu eine Low-Level-API sowie eine Object-Persistence-API. Das Tutorial beschreibt, wie die Object-Persistence-API genutzt wird, um mit Amazon DynamoDB zu kommunizieren. Dazu wird als Beispiel eine DVD Bibliothek erstellt, mit der individuelle DVDs hinzugefügt, modifiziert, gesucht und gelöscht werden können.
Voraussetzungen
Schritt 1 – Einrichten der Umgebung
Zunächst wird in Visual Studio ein neues Projekt angelegt und die Umgebung eingerichtet.
Dazu muss eine Referenz zu der AWSSDK.dll hinzugefügt werden. Zu finden unter C:[*]Program Files[*]AWS SDK for .NET[*]bin.
[*] bitte durch einen SLASH ersetzen.
Anschließend wird eine neue Konfigurationsdatei für die Anwendung hinzugefügt. Als Standard-Dateiname kann App.config genommen werden.
Nun benötigen wir die AWS Anmeldedaten, also den AWS Access Key und Secret Key.
Wir fügen den folgenden “using” Ausdruck hinzu.
using Amazon.DynamoDB.DataModel;
Und übernehmen den AWS Access Key und Secret Key in die App.config Datei.
Schritt 2 – Erstellen des DVD-Schema
Als Nächstes wird eine Klasse angelegt, die für das Amazon DynamoDB Schema benötigt wird.
Dazu legen wir eine neue Klasse mit dem Namen DVD.cs an.
Und fügen den folgenden “using” Ausdruck hinzu.
using Amazon.DynamoDB.DataModel;
Wir fügen die folgenden Eigenschaften hinzu und überschreiben die ToString Methode.
public class DVD { public string Title { get; set; } public int ReleaseYear { get; set; } public ListActorNames { get; set; } public string Director { get; set; } public string Producer { get; set; } public override string ToString(){ return string.Format(@"{0} - {1} Actors: {2}", Title, ReleaseYear, string.Join(", ", ActorNames.ToArray()));} } }
Nun müssen wir Amazon DynamoDB spezifische Attribute hinzufügen, um die Tabelle, den Hash Key und Range Key identifizieren zu können. Im Folgenden befindet sich der Code der endgültigen DVD.cs inkl. aller notwendigen Attribute.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Amazon.DynamoDB.DataModel; namespace DVDsOnCloud { [DynamoDBTable("DVD")] public class DVD { [DynamoDBHashKey] public string Title { get; set; } [DynamoDBRangeKey] public int ReleaseYear { get; set; } [DynamoDBProperty] public ListActorNames { get; set; } public string Director { get; set; } public string Producer { get; set; } public override string ToString() { return string.Format(@"{0} - {1} Actors: {2}", Title, ReleaseYear, string.Join(", ", ActorNames.ToArray())); } } }
Ein Hash Key ist vergleichbar mit dem Primary Key einer Tabelle. Es wird erwartet, dass dieser immer einzigartig ist und ist der am meisten genutzte Key für Anfragen. Der Range-Key ist ein sekundärer Schlüssel, der von DynamoDB verwendet wird, um einen sortierten Index-Bereich zu schaffen. Obwohl der Range Key optional ist, kann die Kombination von Hash Key und Range Key die Query-Performance optimieren.
Schritt 3 – Erstellen der DVDLibrary Hilfsklasse
Nun erstellen wir einen Wrapper für die DynamoDB API innerhalb einer Klasse, die von einem Client genutzt werden kann. Dazu erstellen wir eine neue Klasse mit dem Namen DVDLibray.cs.
Wir fügen die folgenden “using” Ausdrücke hinzu.
using Amazon; using Amazon.DynamoDB; using Amazon.DynamoDB.Model; using Amazon.DynamoDB.DataModel; using Amazon.SecurityToken; using Amazon.Runtime;
Schritt 4 – Hinzufügen der öffentliche Mitglieder und des Konstruktors
Nun fügen wir den Konstruktor zur DVDLibrary Klasse hinzu. Der Konstruktor verwendet den AWS Security Token Authentifizierung, um die Anmeldedaten zu überprüfen.
AmazonDynamoDB client; public DVDLibrary() { AmazonSecurityTokenServiceClient stsClient = new AmazonSecurityTokenServiceClient(); RefreshingSessionAWSCredentials sessionCredentials = new RefreshingSessionAWSCredentials(stsClient); client = new AmazonDynamoDBClient(sessionCredentials); }
Schritt 5 – Initialisierung der Amazonas DynamoDB Tabelle
In diesem Schritt initialisieren wir Amazon DynamoDB Tabelle. Wir stellen sicher, dass die Tabelle nicht existiert und erstellen eine neue. Zudem konfigurieren wir die benötigten Parameter, wie den bereitgestellten Durchsatz, Hash Key und Range Key. Das Erstellen einer Amazon DynamoDB Tabelle dauert eine Weile. Zu dieser Zeit können keine weiteren Operationen durchgeführt werden. Daher wird die Methode solange blockiert, bis der Status der Tabelle in den Zustand “Active” wechselt.
public void Init() { ListcurrentTables = client.ListTables().ListTablesResult.TableNames; if (!currentTables.Contains("DVD")) { CreateTableRequest reqCreateTable = new CreateTableRequest(); CreateTableResponse resCreateTable=new CreateTableResponse(); reqCreateTable.TableName = "DVD"; reqCreateTable.ProvisionedThroughput = new ProvisionedThroughput(); reqCreateTable.ProvisionedThroughput.ReadCapacityUnits=10; reqCreateTable.ProvisionedThroughput.WriteCapacityUnits=10; reqCreateTable.KeySchema = new KeySchema(); reqCreateTable.KeySchema.HashKeyElement = new KeySchemaElement(); reqCreateTable.KeySchema.HashKeyElement.AttributeName = "Title"; reqCreateTable.KeySchema.HashKeyElement.AttributeType = "S"; reqCreateTable.KeySchema.RangeKeyElement = new KeySchemaElement(); reqCreateTable.KeySchema.RangeKeyElement.AttributeName = "ReleaseYear"; reqCreateTable.KeySchema.RangeKeyElement.AttributeType = "N"; resCreateTable = client.CreateTable(reqCreateTable); while (resCreateTable.CreateTableResult.TableDescription.TableStatus != "ACTIVE") { System.Threading.Thread.Sleep(5000); } } }
Bei Amazon DynamoDB besteht die Möglichkeit, den Anforderungsdurchsatz festzulegen, den eine Tabelle erreichen soll. Der Service sorgt dann dafür, die Ressourcen bereitstehen, mit denen die erforderliche Durchsatzrate erreicht wird. Die Durchsatzanforderungen können in Bezug auf die Lesekapazität und Schreibkapazität in der Tabelle festgelegt werden. Dazu werden beim Erstellen einer Tabelle die erforderlichen Lese- und Schreibkapazitätsanforderungen angegeben. Auf dieser Basis partitioniert Amazon DynamoDB automatisch die entsprechende Anzahl von Ressourcen und reserviert diese, damit der Durchsatz erreicht wird.
Schritt 6 – Hinzufügen einer neuen DVD
Nun erstellen wir eine Funktion mit dem Namen AddDVD, die das DVD Objekt akzeptiert und ein Element in der Amazon DynamoDB erstellt.
public void AddDVD(DVD dvd) { DynamoDBContext context = new DynamoDBContext(client); context.Save(dvd); }
Schritt 7 – Ändern einer vorhandenen DVD
Als Nächstes erstellen wir eine Methode ModifyDVD, die versucht eine vorhandene DVD zu laden, diese zu modifizieren und anschließend zu speichern. Wird das Element nicht gefunden, kommt es zu einer Exception.
public void ModifyDVD(DVD dvd) { DynamoDBContext context = new DynamoDBContext(client); DVD oDVD = context.Load(dvd.Title, dvd.ReleaseYear); if(oDVD==null) new Exception("Non-existent DVD"); context.Save(dvd); }
Schritt 8 – Alle DVDs ausgeben
Um alle DVDs auszugeben, führen wir einen Table Scan durch.
public IEnumerable GetAllDVDs() { DynamoDBContext context = new DynamoDBContext(client); IEnumerable alldvds=context.Scan(); return alldvds; }
Wie bei jeder anderen Datenbank auch, ist ein vollständiger Scan auf Amazon DynamoDB kostspielig. Diese Operation berücksichtigt nicht den Hash Key und Range Key und durchläuft jedes Element. Der Scanvorgang wird beendet, wenn die aggregierte Größe der gescannten Objekte 1MB übersteigt. Der Client muss die Operation für den Rest der Elemente dann erneut starten.
Schritt 9 – DVDs auf Basis des Titels und Erscheinungsjahrs suchen
Um nach den DVDs zu suchen, benötigen wir den Hash Key als auch den Range Key. Daher wird diese Methode beide Schlüssel nutzen, um die DVDs zu durchsuchen.
public IEnumerable SearchDVDs(string title, int releaseyear) { DynamoDBContext context = new DynamoDBContext(client); IEnumerable alldvds = context.Query(title, Amazon.DynamoDB.DocumentModel.QueryOperator.Equal, releaseyear); return alldvds; }
Schritt 10 – DVDs auf Basis des Titels suchen
Wenn das Erscheinungsjahr nicht zu den Suchkriterien gehören soll, nutzen wir nur die folgende Methode, die nur auf Basis des Titels sucht.
public List>SearchDVDByTitle(string title) { DynamoDBContext context = new DynamoDBContext(client); QueryRequest reqQuery = new QueryRequest(); reqQuery.TableName = "DVD"; reqQuery.HashKeyValue = new AttributeValue() { S = title }; QueryResponse resQuery = client.Query(reqQuery); return resQuery.QueryResult.Items; }
Schritt 11 – Löschen der DVD
Mit der folgenden Methode löschen wir eine DVD.
public void DeleteDVD(DVD dvd) { DynamoDBContext context = new DynamoDBContext(client); DVD oDVD = context.Load(dvd.Title, dvd.ReleaseYear); if (oDVD == null) new Exception("Non-existent DVD"); context.Delete(dvd); }
Im Folgenden befindet sich der gesamte Quellcode für die DVDLibrary.cs.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Amazon; using Amazon.DynamoDB; using Amazon.DynamoDB.Model; using Amazon.DynamoDB.DataModel; using Amazon.SecurityToken; using Amazon.Runtime; namespace DVDsOnCloud { class DVDLibrary { AmazonDynamoDB client; public DVDLibrary() { AmazonSecurityTokenServiceClient stsClient = new AmazonSecurityTokenServiceClient(); RefreshingSessionAWSCredentials sessionCredentials = new RefreshingSessionAWSCredentials(stsClient); client = new AmazonDynamoDBClient(sessionCredentials); } public void Init() { ListcurrentTables = client.ListTables().ListTablesResult.TableNames; if (!currentTables.Contains("DVD")) { CreateTableRequest reqCreateTable = new CreateTableRequest(); CreateTableResponse resCreateTable=new CreateTableResponse(); reqCreateTable.TableName = "DVD"; reqCreateTable.ProvisionedThroughput = new ProvisionedThroughput(); reqCreateTable.ProvisionedThroughput.ReadCapacityUnits=10; reqCreateTable.ProvisionedThroughput.WriteCapacityUnits=10; reqCreateTable.KeySchema = new KeySchema(); reqCreateTable.KeySchema.HashKeyElement = new KeySchemaElement(); reqCreateTable.KeySchema.HashKeyElement.AttributeName = "Title"; reqCreateTable.KeySchema.HashKeyElement.AttributeType = "S"; reqCreateTable.KeySchema.RangeKeyElement = new KeySchemaElement(); reqCreateTable.KeySchema.RangeKeyElement.AttributeName = "ReleaseYear"; reqCreateTable.KeySchema.RangeKeyElement.AttributeType = "N"; resCreateTable = client.CreateTable(reqCreateTable); while (resCreateTable.CreateTableResult.TableDescription.TableStatus != "ACTIVE") { System.Threading.Thread.Sleep(5000); } } } public void AddDVD(DVD dvd) { DynamoDBContext context = new DynamoDBContext(client); context.Save (dvd); } public void ModifyDVD(DVD dvd) { DynamoDBContext context = new DynamoDBContext(client); DVD oDVD = context.Load (dvd.Title, dvd.ReleaseYear); if(oDVD==null) new Exception("Non-existent DVD"); context.Save (dvd); } public IEnumerable GetAllDVDs() { DynamoDBContext context = new DynamoDBContext(client); IEnumerable alldvds=context.Scan (); return alldvds; } public IEnumerable SearchDVDs(string title, int releaseyear) { DynamoDBContext context = new DynamoDBContext(client); IEnumerable alldvds = context.Query (title, Amazon.DynamoDB.DocumentModel.QueryOperator.Equal, releaseyear); return alldvds; } public List >SearchDVDByTitle(string title) { DynamoDBContext context = new DynamoDBContext(client); QueryRequest reqQuery = new QueryRequest(); reqQuery.TableName = "DVD"; reqQuery.HashKeyValue = new AttributeValue() { S = title }; QueryResponse resQuery = client.Query(reqQuery); return resQuery.QueryResult.Items; } public void DeleteDVD(DVD dvd) { DynamoDBContext context = new DynamoDBContext(client); DVD oDVD = context.Load (dvd.Title, dvd.ReleaseYear); if (oDVD == null) new Exception("Non-existent DVD"); context.Delete (dvd); } } }
Der komplette Quellcode
Im Folgenden ist der vollständige Code des Clients zu finden, der auf die DVDLibrary zugreift.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DVDsOnCloud { class Program { static void Main(string[] args) { //Create the helper object DVDLibrary DVDLib= new DVDLibrary(); //Initialize DVDLib.Init(); //Create the DVD object DVD dvd = new DVD() { Title = "Businessman", ReleaseYear = 2011, ActorNames = new List{ "Mahesh", "Kajal" }, Director = "Puri Jagannath", Producer = "Venkat" }; //Add the new DVD DVDLib.AddDVD(dvd); //Print all the DVDs foreach (var odvd in DVDLib.GetAllDVDs()) Console.WriteLine(odvd.Title); //Create a new DVD object with modified values DVD newdvd = new DVD() { Title = "Businessman", ReleaseYear = 2011, ActorNames = new List { "Mahesh Babu", "Kajal Agarwal" }, Director = "Puri Jagannath", Producer = "Venkat" }; //Commit the changes DVDLib.ModifyDVD(newdvd); //Search for the DVD foreach (var dvd in DVDLib.SearchDVDs("Businessman",2011)) Console.WriteLine(dvd.Director); //Delete the DVD DVDLib.DeleteDVD(newdvd); } } }
Quelle: http://cloudstory.in