(upbeat music)
- Welcome to the Azure Cosmos DB Essentials Series season 2.
My name is Mustafa,
I am a Product Marketing Manager for Azure Cosmos DB.
And in the last episode, we walked us through some things
to know when choosing an API,
as well as introduced some concepts we need to understand
on day one of using Azure Cosmos DB.
This episode will explore the topic of the Request Units,
which are fundamental to pricing and capacity planning
in Cosmos DB.
So, lets start with the question, what is a Request Unit?
A Request Unit is a unit of compute
and is how Azure Cosmos DB charges for database operations.
Whenever you make a request into the database,
so let's say we have a request that goes into the database
and a response that comes back out,
and our request is a query, for example,
"Hey, database find me all of the information
where the first name is Andrew".
What you're really doing,
is you're in the back end using up some CPU,
memory and IOPs or Input Output Operations.
Now the game we're usually playing here
is capacity planning.
So if you look at a virtual machine,
you can usually manipulate each of these three dimensions.
You can increase the amount of cores,
you can increase memory in terms of Gigabytes of RAM,
or with IOPs,
you can typically look at whether you have a hard disk,
an SSD, or an array of any of them.
For a lot of different vendors,
including some of our Azure services,
when working with virtual machines,
what we'll do is we'll give these three things: CPU, Memory,
and IOPS, in the form of different managed disks,
with for instance 4 cores, 8 Gigabytes of Ram, etc.
When capacity planning,
there are a couple characteristics of Request Units
that make the approach different
to working with traditional VMs.
So, fist let's look at virtual machines,
the first thing we would need to do
is determine the right size for our app.
So how much of these three things: CPU, memory, and IOPs,
are needed for our use case?
Now mixing these three factors plus storage,
offers different database performance characteristics,
but figuring out exactly how much of each to provision
can be difficult.
The goal of Request Units
is to make capacity planning simple.
So what we do is establish that 1 RU
is going to be equal to 1 point read of 1kb of data
as a rule in Cosmos DB.
And with that rule in mind,
we can now determine how many requests units
we need to provision.
If you run a query that returns,
say twice as much information,
what you'll see is that double the RUs are going to be used.
RUs are Azure Cosmos DB's logical currency.
So let's go through an example of how capacity planning
is simpler with the concept of a Request Unit.
If I have a workload that has 100 reads per second,
and I don't know 200 writes per second,
if it takes say 4 RUs per read, and 8 RUs per write,
then the amount of overall compute that's needed for this
on the read path at 100 reads per second,
is going to be 400 Request Units,
and on the write path at 200 writes per second
we're gonna need 1,600 Request Units.
That puts our capacity planning result
at 2,000 Request Units per second.
Now this is obviously a simple example,
but we actually have a pricing calculator
that lets you input the document size, number of reads,
inserts, updates, writes, deletes etc,
with all of the RU approximations
for each operation already populated.
This allows for us to just fill in
what we know about the size of the data we are reading,
and how many reads or writes we think our application
is going to need in order to get a more granular estimation.
Additionally, you can also just upload a sample document
to the calculator, fill out a few fields,
and it will throw you an RU estimation which is pretty cool.
This granular estimation,
is really only necessary when provisioning manually.
And we offer a few different provisioning models,
such as Serverless and Autoscale,
that eliminate the need to do such an exact estimation.
So what are the characteristics of an app workload
that might make you lean toward one model over another?
To answer that we'll start at the very top level.
Cosmos DB offers a provisioned Throughput model
as well as a Serverless model.
With the provisioned Throughput model,
there's a few things you'll wanna think about.
Which are whether you wanna it manually configure the RUs,
versus turn on Autoscale.
Starting with Serverless, the more simpler option,
it's a consumption-based model,
where over the lifetime of the month,
it's going to bill based on the number of requests consumed.
So if I over the course of the month ran only two queries
and those two queries cost, let's say 5 RUs each,
then I will over the lifetime of the month
have consumed 10 RUs.
With Serverless priced at $0.25 per 1 million Rus,
it's pretty cheap to use Serverless.
Now, I can also configure the Cosmos DB account
for provisioned Throughput,
in which case when we go and create our database,
both databases and containers
can have a Manual amount of provisioned Throughput,
or an Autoscaling amount of provisioned Throughput.
Manual provisioned Throughput
will bill for the number of provisioned requests,
regardless of how many are consumed,
and Autoscale will bill for the peak number of requests
received within an hour window.
So if you have 100 requests during an hour,
and then 10 requests the next hour,
the first hour will be billed as if manually provisioned
at 100 requests and the second hour will be billed
as if manually provisioned for 10 requests at that hour.
To understand when we should use one over the other,
I'll illustrate this with a graph.
Now imagine that I have a graph here,
where the X-axis is of course time
and the Y-axis is the number of requests per second.
If the shape of my graph looks something like this,
let's say I have a Dev Test Workload
where most of the time it's idle,
but once in a while I'm developing in the morning,
I run some queries and then it's idle,
and then I go to lunch, run a few queries,
and then in the afternoon I run some queries again,
but overtime I actually find that a good amount of my work
doesn't always need a live database.
So the utilization, if I look at this graph, is fairly low.
Like I have these intermittent spikes,
but otherwise the workload is pretty much idle.
It may be a Dev Test Workload or it may even be
a line of business application in production.
In the second graph,
let's have a live website where I always have some traffic.
But then suddenly,
my application makes the front page of Reddit
and so I'm getting a lot more traffic.
Then overtime the traffic fades after the initial burst.
In this third graph, we're going to look at,
let's say an IOT device telemetry scenario,
with a message queue and a growing number of devices,
let's say 1,000 devices that grows to 2,000 devices,
that goes to 3,000 devices,
but nonetheless what happens is the workload is predictable
and just sends a heartbeat every second.
Today when I have 1,000 devices,
I can approximate that to be just 1,000 requests per second
and then accounting for some network latency and jitter,
but for the most part,
the Throughput on that is gonna be very flat.
When I look at each of these scenarios,
we notice the shape of that curve looks very different.
Now if I were to go in, look at the last graph,
the IOT device telemetry scenario,
this one is something
where we can give it guaranteed performance
by manually provisioning Throughput,
based off what the workload needs are at that time.
Now in the middle scenario,
what you notice here is this is the live website
that gets like a big social media bomb,
if I were to provision the manual provisioned Throughput,
what you'll notice is, that there's a lot of waste here.
So, this isn't the most cost effective way to provision
in this case.
By using Autoscale,
what we can do is we can put an upper threshold
on how much traffic we want the database
to be able to support.
And what the Cosmos DB Autoscale does
is it actually scales at a 10X scaling range,
and automatically scales Throughput within that range.
So if I go and set Autoscale
rather than a provision model for the peak,
if I set this as the max of my Autoscale,
then what I'll do is the actual
will look something like this
and all of this a difference between the max
versus the actual is the amount of money
that Autoscale can save our workload.
In the first scenario this might look like a time
when we wanna use Autoscale as well.
But what's happening is,
because we have these large periods of idle,
an Autoscale never goes down to zero
as part of the performance proposition
of a provisioned Throughput model.
With Serverless, we decide to say,
we don't need guaranteed Throughput
when our workload is zero,
what we're looking for is most of the time,
the database is going to be idle,
what we'd like to do is pay based off the consumed requests
and that's it.
So again, Serverless is a really cost effective way
to run production and Dev Test Workloads
with intermittent Throughput needs.
Now with the manually provisioned Throughput model
from the IOT scenario,
let's talk about whether we should be provisioning
at the container or database level.
If we're in the portal, we just created an account,
and underneath the account you have a database,
and 3 containers: containers 1, 2, and 3.
If we provision at the container level,
then we are in essence binding that container
to a set of one or more nodes serving requests.
And we'll effectively call these partitions,
which we'll cover in the next episode on partitioning.
If we provision 5,000 RUs to container 1,
and 25,000 to the other two containers,
then we effectively have provisioned 10,000 RUs
between our three containers.
If we do the provisioning at the database level,
then we can provision 10,000 RUs to be shared
across those three containers tying the database
to a few nodes rather than a single container.
Typically speaking, in most scenarios,
what we end up seeing is you'll have one container
that's very large
and then you have many small metadata containers.
And what we advocate for is having the small container share
a database level Throughput and having
the one large container have its own dedicated Throughput.
All right, so that concludes the second episode
about Request Units, capacity planning,
and the difference between different provisioning models
in Cosmos DB.
Tune into the next episode on partitioning strategy
to learn more about things to know on Day one
of getting started with Cosmos DB.
(upbeat music)