Amazon DynamoDB zusammen mit .NET nutzen

[ 3 ] März 1, 2012 |

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 List ActorNames { 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()
{
    List currentTables = 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()
        {
            List currentTables = 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

Tags: , , , , , ,

Category: Tutorials

René Büst

About the Author ()

Rene Buest is Senior Analyst and Cloud Practice Lead at Crisp Research, covering cloud computing, IT infrastructure, open source and Internet of Things. Prior to that he was Principal Analyst at New Age Disruption and member of the worldwide Gigaom Research Analyst Network. Rene Buest is top cloud computing blogger in Germany and one of the worldwide top 50 bloggers in this area. In addition, he is one of the world’s top cloud computing influencers and belongs to the top 100 cloud computing experts on Twitter and Google+. Since the mid-90s he is focused on the strategic use of information technology in businesses and the IT impact on our society as well as disruptive technologies. Rene Buest is the author of numerous professional cloud computing and technology articles. He regularly writes for well-known IT publications like Computerwoche, CIO Magazin, LANline as well as Silicon.de and is cited in German and international media – including New York Times, Forbes Magazin, Handelsblatt, Frankfurter Allgemeine Zeitung, Wirtschaftswoche, Computerwoche, CIO, Manager Magazin and Harvard Business Manager. Furthermore Rene Buest is speaker and participant of experts rounds. He is founder of CloudUser.de and writes about cloud computing, IT infrastructure, technologies, management and strategies. He holds a diploma in computer engineering from the Hochschule Bremen (Dipl.-Informatiker (FH)) as well as a M.Sc. in IT-Management and Information Systems from the FHDW Paderborn.

Leave a Reply

You must be logged in to post a comment.