NoSQL with DynamoDB on AWS
In the world of databases, DynamoDB is a game-changer. This NoSQL database service by Amazon Web Services (AWS) offers unparalleled benefits, making it a superior choice for specific use cases compared to traditional relational databases. Today we'll explore what makes DynamoDB stand out and why it could be the perfect fit for your data-driven needs.
More importantly we're also going to show just how easy it is to include DynamoDB in your application space. With a few lines of code you can be using DynamoDB to turbo-charge your applications!
What is DynamoDB
DynamoDB is built on a combination of various technologies, including the principles of distributed computing, partitioning, and replication. It employs a distributed architecture that
allows it to provide seamless, low-latency access to data, making it ideal for applications with varying workloads and high demands. DynamoDB was officially launched by AWS in 2012, and
since then, it has evolved into a leading choice for businesses and developers looking for a robust and scalable database solution, particularly for cloud-based applications and services.
We love AWS and have built FTP2SF on AWS to enable easy access to FTP, SFTP, Azure Blob and AWS S3 services, recently we have been looking at ways to maximise
some of the processing through-put around our data analytics and the transitory data that we utilise during a processing cycle so of course we looked at DynamoDB.
Why did we focus on DynamoDB rather than an alternate Database technology?
-
Data Model in DynamoDB
DynamoDB employs a schema-less data model, which is markedly different from traditional databases. Instead of tables with fixed schemas, data is organized into tables, items, and attributes. This model allows you to work with semi-structured or unstructured data, making it an excellent choice for various applications. -
Partitioning and Scaling
One of DynamoDB's defining features is its ability to scale horizontally. Data is distributed across multiple partitions to ensure rapid access and high availability. This allows DynamoDB to handle a virtually infinite number of read and write requests per second. The auto-scaling feature automatically adjusts capacity in response to changes in demand. -
Data Encryption
Data security is paramount. DynamoDB provides encryption at rest and in transit. At rest, data is encrypted using AWS Key Management Service (KMS), ensuring robust protection. In transit, DynamoDB supports SSL/TLS encryption, safeguarding data during transmission. -
Speed
One of the standout features of DynamoDB is its blazing-fast performance and limitless scalability. Traditional databases often struggle to keep up with the demands of modern web applications, especially when it comes to handling massive volumes of data. DynamoDB, on the other hand, excels in this aspect. With DynamoDB, you can effortlessly scale your database to handle millions of requests per second. It's a fully managed service, which means you don't have to worry about server provisioning or maintenance, allowing you to focus on your application's growth.
So how does it work
I think the easiest way to show how easy DynamoDB is to use is to show a simple cache service, so lets go!
The Key (no-pun) to using DynamoDB is to first define your object definition, fortunatly this is incredibly easy in C#, you define this as you would any other class and add some additional decorators:
[Serializable]
[DynamoDBTable("cache")]
public class DynamoDBKeyValue
{
[DynamoDBHashKey] // Key attribute
public string Key { get; set; }
[DynamoDBProperty] // Value attribute
public string Value { get; set; }
}
In our example I'm just using a very simplified Key Store, in reality you would probably want to expand this example out a little. One of the advantages to this simplicity though is that strong JSON
within the Value property allows significant flexibility with how we would use this cache.
Note the use of the DynamoDBTable decorator, this matches the tablename that you create within the AWS Console.
public static void SaveCache(KeyValuePair keyValuePair)
{
AmazonDynamoDBConfig config = new()
{
MaxErrorRetry = 3,
Timeout = new TimeSpan(0,0,5),
RegionEndpoint = RegionEndpoint.APSoutheast2
};
using (var client = new AmazonDynamoDBClient(AWS.KEY, AWS.Secret, config )) // Initialize the Amazon DynamoDB client
{
var context = new DynamoDBContext(client); // Create a DynamoDB context
var keyValueTable = new DynamoDBKeyValue
{
Key = keyValuePair.Key.ToUpper(),
Value = keyValuePair.Value
};
CancellationToken token = new CancellationToken();
var saveTask = context.SaveAsync(keyValueTable,token);
if (!saveTask.Wait(5000, token))
{
throw new TimeoutException("The cache save timed out.");
}
token.ThrowIfCancellationRequested();
saveTask.Wait(token);
if (!saveTask.IsCompletedSuccessfully) throw new Exception("Cache initialization failed");
}
}
As you can see from the above save - we are passing the regional endpoint, key and secret to create an instance of DynamoDB, we allow for a specified timeout and retry count to allow the save
to complete within the required period and throw a simple exception if it fails. Reading the content of the Key Value store is just as easy.
public static string LoadCache(string key)
{
AmazonDynamoDBConfig config = new()
{
MaxErrorRetry = 3,
Timeout = new TimeSpan(0, 0, 10),
RegionEndpoint = RegionEndpoint.APSoutheast2
};
using (var client = new AmazonDynamoDBClient(AWS.KEY, AWS.Secret, config)) // Initialize the Amazon DynamoDB client
{
var context = new DynamoDBContext(client); // Create a DynamoDB context
var keyValue = new DynamoDBKeyValue // Create a DynamoDBKeyValue instance with the key you want to use
{
Key = key.ToUpper()
};
// Retrieve the item from DynamoDB using the key value
var loadTask = context.LoadAsync(keyValue);
CancellationToken token = new CancellationToken();
if (!loadTask.Wait(15000, token))
{
throw new TimeoutException("The cache load timed out.");
}
token.ThrowIfCancellationRequested();
if (loadTask.IsCompletedSuccessfully && loadTask.Result != null)
{
context.DeleteAsync(keyValue).Wait();
return loadTask.Result.Value;
}
return null;
}
}
In the read method I'm choosing to explicitly Delete the Key once the Read has occurred - the alternate approach is to set a TTL within the object structure and allow DynamoDB to automate the
removal after a specific time period.
While this is a limited example, it also shows just how quick and easy using DynamoDB is within your application, nuget the Amazon.DynamoDBv2 packages within your C# Application, add a few lines of code and you're done.
Thanks again for reading, feel free to reach out if you need some help or support. We're always here to help!