How to Use Caching with Azure Cosmos DB

Recorded webinar
By Ron Hussain and Sam Awan

Azure Cosmos DB is a globally distributed multi-model cloud-based NoSQL database service. It is a very popular NoSQL database service for high transaction applications because of its simplicity of deployment and the strong SLAs by Microsoft.

You can further scale up CosmosDB with NCache. NCache being in-memory means it is super fast. And, NCache being distributed means it can scale linearly. Also, NCache sits much closer to your application and hence is much faster to access. Learn how to incorporate distributed caching into your Azure Cosmos DB application by using NCache.

In this webinar learn how to improve your Azure CosmosDB performance with NCache.

This webinar covers:

  • Introduction to Azure Cosmos DB and its common operations
  • Caching of CRUD data in Azure Cosmos DB application using NCache
  • Handle Caching of Collections
  • Managing Cache Synchronization with Azure Cosmos DB
  • Hands-on Examples and demonstrations throughout

Today's topic is going to be speeding up Microsoft Azure Cosmos DB with the help of NCache. NCache is our main distributed caching product at Alachisoft. You can use it within .NET, .NET Core or Java applications or any other general applications and you can improve your application’s performance, scalability and reliability. Today we will talk about caching options that you can utilize alongside Azure Cosmos DB. Because Cosmos DB is also getting very popular. It’s a very important NoSQL database. So, I have lined up some hands-on examples to get you guys started with caching with Cosmos DB and using NCache as an example product for that. So, I believe everything looks good. So, let's quickly get started and if there are any questions while I am presenting different features, please feel free to stop me and post as many questions as you need to and Sam will keep an eye on those questions and we'll answer those questions down the line.

Introduction to Azure Cosmos DB

First few slides are pretty basic slides around introduction to Microsoft Azure Cosmos DB. I'm pretty sure everybody knows, what Azure Cosmos DB is? But just for the sake of completeness, it's globally distributed multi-model database. So, you can use it anywhere. It’s a hosted fully managed hosted database service within Microsoft Azure and it's a multi-model database. That essentially means you can use key value, you can use table family, you can use SQL API, there is a MongoDB Connector and then there's a Gremlin API as well for graphs. So, it gets you a lot of different ways where, using those, you can use Cosmos DB within your application as a database.

So, it's essentially a NoSQL database but Microsoft claims it to be a multi-model database. So, it's slightly more than NoSQL database in that particular regard. So, it's a multi-model database as per the definition and it's very flexible, ease of deployment because it's a fully managed database service. So, you just need to use the NuGet packages within your application and point to your Cosmos DB instance in Microsoft Azure. If it's an on-prem application you can still be able to connect to Microsoft Azure Cosmos DB for that matter and it's backed up by comprehensive SLAs by Microsoft. So, it's fully managed, so, you don't have to worry about any deployment or any other issues for that matter. It supports a very flexible JSON format. So, you can use unstructured documents data. You can just create a document using JSON format and then push it to Cosmos DB and then that's what you retrieve. So, it's very flexible, very easy to use, less code needed in order to get started with this and it's very popular in the high transactional applications. You can have your web apps using it. These could be web services, microservices, back-end server applications. Any sort of applications can utilize Microsoft Azure Cosmos DB, if there is a need to ingest process and deal with a lot of data within your applications.

Here is a diagram which again talks about table, SQL, JavaScript, Gremlin, Spark. So, different connectors that you can utilize and then most common one is key value. Then there's a column family, documents with nested documents and then Gremlin for graphs as well. So, you can store graphs.

msdn-diagram

So, it's something which is globally distributed as well. In Microsfot Azure you can have multiple datacenters. You can also have multiple partitioning. So, all the good stuff that comes along with Microsoft Azure Cosmos DB.

Common Use Cases of Cosmos DB

Some of the common use cases. You can use it in IoT and Telematics to ingest, process and store a lot of data and typically, if you're dealing with high transactional applications in this particular industry, you can use Cosmos DB and you don't have to worry about managing that amount of data and managing those amount of requests as well. Regional marketing for storing catalog information, event sourcing, order processing, gaming where database tier is crucial component. So, you can have multiple gaming apps utilizing or there could be different players interacting with one another. Tournament’s information, high score leaderboards and social media integration for that matter.

Web and mobile applications, that could be another use case for it. Social applications could be another example integrating with third-party services. So, you can utilize it in almost any application that needs to deal with a lot of data, ingest process and store a lot of data for that matter. So, Cosmos DB could be a preferred choice for it. Now, I think this is good, detail in terms of introduction. Please, let me know if there are any questions.

Today's focus is what are the requirements for caching, right and why do you need caching for that matter? And for that, there are two problems with Microsoft Azure Cosmos DB and this is based on the performance test that we've done and based on the request unit cost estimations that we've done.

Problems with Azure Cosmos DB

So, there are primarily two problems with Microsoft Azure Cosmos DB.

Performance Bottleneck

Number 1 and most crucial one is the performance bottleneck. Microsoft Azure claims that Cosmos DB is going to give you millisecond response time, right and that's pretty much true based on our testing results as well but what if you need sub millisecond responses? Because with NCache within our local testing even a local cache, we're not talking about different partitioning or having multiple servers hosting the cache data, even a local cache it could be across network as well, is able to get you sub millisecond responses and based on our comparisons we tested Cosmos DB with NCache.

So, the performance difference is huge when you compare Microsoft Azure Cosmos DB with NCache. So, from seconds to milliseconds and from milliseconds to sub millisecond response times, you can see that Cosmos DB need performance improvements. Primarily, once we analyze it a little bit more, it's primarily because of the fact within your application when you would go ahead and deploy it in production your Microsoft Azure Cosmos DB is a hosted service. So, it would always be across VNET in its own subscription. It could be permit part of your subscription and they charge you based on the request unit but it's hosted within Microsoft Azure and your application, if it's already hosted in a virtual network, if it goes across VNET that's where it has to have the network cost added to it and that increases the latency part as well.

So, that's one and secondly, if your applications are on-prem, your applications are going to be further slower as well. So, initially I talked about basic comparison between Cosmos DB and NCache. NCache is already faster because it's in-memory and it gives you sub millisecond responses in comparison to millisecond and then on top of it, when you would actually deploy it and your applications are going to be hosted in cloud. Azure’s Cosmos DB is going to be across VNET and from VNET-to-VNET communication, there is a significant latency which could come into play and if you have multiple partitioning and then you have two datacenters and data is going back and forth and if you end up going to another partition or another datacenter, things would be further slow in comparison and then on-premise. That's not a very common use case, where on-prem applications are using Microsoft Azure Cosmos DB but if that's the case then you have to go across WAN in order to access the Cosmos DB. So, that's not a very fast option.

So, that's number one issue that Microsoft Azure Cosmos DB is not very well deployed in terms of performance. So, your performance is going to be degraded specifically under high transaction. When you have a lot of requests coming in and you need to deal with that data in a fast timely manner. So, it may give you some performance degradation and solution is very simple, which we'll cover in next slide that you start using a caching system like NCache.

Expensive Request Unit

Problem number two is the cost expensive request unit and that's something which hurts you in dollars. So, each request unit has a cost. Each time you access Microsoft Azure Cosmos DB, even for the read-only data. If that data is not being changed that frequently, it's the same content but you still have the master source coming from the Cosmos DB that's the data that you're looking in. For that data you have to keep going back and forth to Microsoft Azure Cosmos DB and that's where you pay in terms of request unit and that increases your cost. So, costs would go up if your request load increases. So, it's very scalable, as far as requests load that it can handle but it's not going to be very cost friendly in that scenario. So, it's going to impact the cost factor as well. So, it could be a potential hurdle for scaling out. When you're planning to scale out. You have multiple partitions, you have your data load increasing but the cost factor goes up alongside that.

So, you may have to consider these two problems when you're dealing with Microsoft Azure Cosmos DB.

The Solution: NCache Distributed Cache

Solution to these problems is very simple that you use a distributed caching system like NCache. First of all, NCache is in-memory. So, everything that you store in NCache is going to be stored in-memory in comparison. So, it's going to give you some millisecond performance improvements right away and then we've done a comparison between Cosmos DB running on localhost, on the same machine and NCache running on the same machine, NCache was a factor faster. It was a lot more faster in comparison. It was in sub milliseconds in comparison to millisecond responses for the same set of data.

Secondly, it's can be hosted within your application of network as well and you can use it addition to the Cosmos DB. It's not a replacement of Cosmos DB. In this particular webinar I will explain different approaches where you can use Cosmos DB alongside NCache and NCache is going to be a helping product, where it would cache most of your data and ensure that it saves expensive trips to the Cosmos DB in terms of cost and in terms of performance. Secondly NCache is a distributed cache cluster. So, it can scale out accordingly. High availability is built into it and it's very reliable as well because there are number of servers and each server has a backup on another server as well and here's a deployment diagram which helps support this.

deployment-arch

You can have any kind of application ASP.NET or ASP.NET Core web apps .NET or .NET Core web services and then similarly, any other server application even Java applications. Previously, if they were using Cosmos DB in cloud or your applications were on premise or everything was it in cloud, you can introduce a caching tier on the same lines. In Microsoft Azure you can just use NCache in Azure using .NET or .NET Core installation. It's available in Microsoft Azure marketplace as well and then you can form a cache cluster and nice thing about NCache is that is going to sit in within your own VNET. So, network latency is going to be completely mitigated. So, that's not an issue anymore and on top of it, NCache is in-memory.

So, NCache is already very fast in comparison. So, performance is going to be improved right away and for your on-prem applications, you can keep NCache on-prem as well and Cosmos DB can still reside in Microsoft Azure cloud and that would just change everything in terms of performance. In terms of cost units, you can store all of your data. As you can see 100% traffic can be routed to NCache and that would in turn save expensive trips to Microsoft Azure Cosmos DB and as soon as you would save trips to Cosmos DB that would help you in terms of saving cost because request unit would go down. You would have less request unit footprint and you would have less costs associated with accessing and using Microsoft Azure Cosmos DB in comparison. Only 20% or even less traffic can go to Microsoft Azure Cosmos DB and we'll talk about these caching options which would help benefit your applications.

So, please let me know, if there’re any questions? We've built some basic details about why you should consider using product like NCache to improve your application. Next thing, I'm going to talk about is going to be common use case of NCache and then we'll have some samples, which I would like to demonstrate. So, please let me know if there’re any questions at this point. Assuming there are no questions at this point. So, I'm going to continue.

Common Uses of NCache

Some of the common use cases. We initially talked about industry wide use cases. So, all of these applications can use NCache as well. As a matter of fact, NCache has a bigger set of clients, variety of clients, which are using NCache. So, it could be E-commerce, it could be banking, it could be financial, it could be automation, it could be IoT, telecom sector. So, every sector has potential of NCache because you can utilize NCache in typically all applications which are dealing with data. They need performance, they need scalability, they need high availability and reliability and they're dealing with these issues. So, they're prime candidates for NCache. But as far as technical use cases are concerned, you can use NCache for application data caching.

Application Data Caching

So, first use case is app data caching. In Microsoft Azure Cosmos DB, you have Cosmos DB as your primary source. That's where most of your documents or all of them would exist and then some or all can be brought into NCache for faster access. So, to improve performers and to decrease the request unit effect on your application and you can have different kind of synchronization approaches, which I'll cover in this webinar as well. So, that's our most common use case in regards to relational databases as well as in regards to Cosmos DB as well.

Ron, I have a question for you and the question is how the same Cosmos DB with NCache, changes with NCache? Okay, I just talked about it. So, we have a segment lined up for this. We have a mechanism within Microsoft Azure Cosmos DB. It uses change feed. There's an observer pattern. So, it allows you to manage add and updates and it keeps track of those add and updates in change feed. So, I have two approaches which are lined up with in this webinar, where I will talk about how to use those change feed notifications to help apply those changes in NCache as well. So, as soon as there would be change, the Cosmos DB database it would automatically be applied in NCache as well. So, that's something which I've lined up in one of the demos today.

Sessions Caching and SignalR Backplane

Some other use cases as well. We have ASP.NET and ASP.NET Core web apps can also use NCache for sessions, for SignalR, for response caching, view state and output cache and then NCache is also a messaging platform as well. You can use Pub/Sub messages. SignalR is backed up by Pub/Sub messaging. We have data-driven events, we have Pub/Sub events and then we have continuous query events as well. So, NCache can be used as a message bus, as a message platform and data sharing platform.

Hands on Demo

All right, I'm going to quickly show you how to get started with NCache. So, that we just create a cache and then we'll talk about different approaches. How to go about caching and how to get started with this? So, few basic examples then we'll actually, we'll build on top of it and show you how to use synchronization and how to manage collections and updates.

So, first of all, I'm going to get started with my demo environment. NCache can be hosted on-prem as well as in Microsoft Azure Cloud. The preferred deployment option for NCache is VM and we have web-based management tool, which allows you to manage Windows boxes as well as Linux boxes. So, with the help of .NET Core you can install NCache on Linux as well. So, it's entirely up to you. Whether you want to keep your cache on VM on Windows or on Linux side. I'm using Windows boxes. So, let's go ahead and create a cache. So, first of all I'm going to create.

create

I'm going to start this wizard right here. I will name my cache Democache.

democache

I'll keep everything default and details about these settings are available within our documentation, as well as in our other webinars, which are more focused on NCache architecture. So, I will keep partitioned replica cache. That's the most preferred one.

partitioned-replica

Async replication between the active partition and the backup of this. If there are two servers, sever one would have backup on two and server two would have backup on one. So, maintaining that backup can be synchronous or asynchronous based on the requests which are coming in. So, I'll choose async because it's again very fast and preferred as well. So, I'm going to specify two servers, which are going to host my cache.

cache-partitioned

NCache is already installed. These are Windows boxes. I'll keep everything default as far as TCP/IP settings, NCache is a TCP/IP based protocol. So, it needs an IP address and a port to communicate with one another and it takes it from there and then I will keep everything default on the screen as well and I'll start this cache on finish.

finish

So, this gets configured as well as started right away and this will take some time and it would automatically create the cache and I have my Azure Cosmos DB emulator right here. I'm using a localhost deployment of it. I have two document stores here, customers and leases.

documents

Leases is again for synchronization through change feed. I will talk about it shortly or at a later point when we will talk about synchronization. So, customer, it's basic customer store document store where we have different customers. If I click on the customers, you can see I have customers with the name, ID, address, city and country and these are the ones which I'm going to manipulate throughout this demo.

{
   "id": "Customer:CustomerID:TRAIH",
   "CustomerID": "TRAIH",
   "CompanyName": "Trail's Head Gourmet Provisioners",
   "ContactName": "Helvetius Nagy",
   "Address": "722 DaVinci Blvd.",
   "City": "Kirkland",
   "Country": "USA",
   "_rid": "Xpd7ANtwbZjSAAAAAAAAAA==",
   "_self":"dbs/Xpd7AA==/colls/Xpd7ANtwbZI=/docs/Xpd7ANtwbZjSAAAAAAAAAA==/",
   "_etag":"\"00000000-0000-0000-1649-a9a8daaa01d5"
   "_attachements": "attachements/"
   "_ts":1559153371
}

So, coming back right here, my cache is fully started. I can check this and view details and I can add my box as a client. That's an optional step. If you're using NuGet package you can skip this step but I will for the sake of ease of use. So, I would just add everything from the GUI manager so, I have configuration populated on my client machine. I think we're good. I will do one other thing. I will open statistics window and I'll also open monitoring tools which comes installed with NCache. So, these give me performance counters and these windows are NCache monitoring tools, see the little bit of monitoring aspects of NCache as well and then I will open a PowerShell window and then I will run a stress testing tool application, which comes installed with NCache and I'll right after this, we'll talk about the sample application, which I've lined up for Cosmos DB. That’s the tool which will simulate some dummy load on my cache cluster and as soon as it hits, I should be able to see some activity. One client is connected.

cluster-health

And you should see requests per second popping up, showing some activity as well and as a matter of fact I can just log on to this box right here, show you this from a different machine so, that we get a faster view of this. All right, you can see activity here. I think the GUI tool is not able to refresh. I think there are some permission issues. But nevertheless, you can see count being updated and then you can see requests per second and that's what all what we need for this particular demo.

statistics

App Data Caching with Azure Cosmos DB

So, I'm good to go with the sample application. I will quickly talk about the app data caching use case and as part of that I will also explain, how my sample application works and then we'll go step-by-step debug the sample application and I'll show you the commands, which I've integrated to get started with the caching. It's a very simple, basic program. It’s a hello world initially and then it progresses from there.

So, we have app data caching. First thing that you need to do is, deal with reference data. Data which does not change that frequently and it could be transactional data as well, which is changing and for that I have separate segment lined up but for reference data, you will primarily be dealing with reads, right. So, you need to first of all connect to the Cosmos DB and then connect to NCache. You need to perform get operations and then you also need to a perform update operations. Within get operations you can cache a single document or a document collection and then for within update you can have add, update and delete documents. So, these are the code snippets and these are going to be highlighted right here.

//Add NCache Nuget and Include Namespaces  	
using Alachisoft.NCache.Client;
using Alachisoft.NCache.Runtime.Caching;

//Add Cosmos DB Nuget and Include Namespaces
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
...
{	
	//NCache Connection call 	
	static ICache _NCacheClient = CacheManager.GetCache("DemoCache");

	//Cosmos DB Connection call
	static DocumentClient _CosmosDbClient = new DocumentClient(
		serviceEndpoint: new Uri("https://localhost:8081"),
		authKeyOrResourceToken:@"C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==");
}...

So, within my CRUD NCache Cosmos DB sample application, I have different cases, different test cases. So, first of all I would just go ahead and provide the cache name which is DemoCache. It’s not case sensitive and then I have some Cosmos DB connection settings. I'm using SQL client, as an example for this because that's the most relevant from a standpoint of examples that I've chosen. But you can come up with any client from Cosmos DB and still be able to use NCache because the NCache API is pretty straightforward. It can get the response, which could be a JSON object and you can cache it, using NCache APIs and within NCache we have different ways of interacting with cache as well. So, you can choose from those but idea for caching remains exactly the same.

All right. So, within my Cosmos DB if you come right here, within this you can see URL, primary key, connection strings. So, these are the settings that you need to specify right here and then you can open a connection. So, this is how you get a cache handle “_cache”, ICache interface, right. If I show you this, this also gives you some of the management APIs as well, right. Let me just, alright and the CacheManager class also, it gives you a cache collection. It has ICache, CacheHealth and some other StartCache and StopCache methods for that matter. Once you're connected to this, first thing that you need to do is, you simply fetch a cache item, right, fetch some documents from the Cosmos DB and then also cache it. But since we're using NCache in the middle, so, our application should be designed in such a way that you should always check first in the cache and that's how you would save expensive trips to the Cosmos DB as well and this is exactly what's going on within our case one right here.

What we're really doing is we're getting a customer ID, that we're planning to get. It could be a customer ID, a fetch based on customer ID and first of all, I will making a call “_cache.Get” and providing a key. Key is something that you define in NCache. NCache stores everything in a key value pair. So, key could be customer, customer ID could be at the runtime parameter for it and then if you find data from cache, you don't have to go to the Cosmo DB. You can return from this point. If you don't, you always execute the Cosmos DB API. For example, in this case it's getting a response using Cosmos DB “_client.ReadDocumentAysnc” and in providing all the details for example, CollectionID and the key and based on that, it would fetch records from Cosmos DB and then also cache it. This is to ensure next time, you already have the data in the cache.

So, I'll run the sample without debugging for the first time. Show you all the test cases and then we'll go through these test cases one by one and I will demonstrate that this is how it is going to perform. Please let me know, if there are any questions?

So, I'm going to add a customer. Let's say I will just provide Ross123, hit enter and then next is that you review a customer, again I can just give Ross123 and you can see that it created a dummy customer Ross123 with contact name, it apended the date and the time to that.

cmd

I can just look for other customers, which are already in the Cosmo DB as well. So, it got that and based on that as we're doing this, you should be able to see two items in the cache Ross and ALFKI already added in the cache.

count

So, I can keep doing this. I can update this customer. For example, Ross123. It's not taking any parameters. It’s simply updating the date/time value. So, if I hit this again you can now see 14:27:13 in comparison to 14:26:37. So, it updated this in the cache as well as in the Cosmos DB as well and if I show you this right here, I can quickly show you the updated customer in the Explorer pane and it has the updated value. So, it's dealing with these two sources side by side. I can delete this customer as well. I can view customer based on actually, let me just get rid of these break points. Okay, it's going to get me all the customers, if I hit 5 and then if I hit 6, it is going to get customers based on a country.

So, first thing that I wanted to highlight is getting a customer from cache using Cosmos DB and NCache, caching a single document. So, let's quickly review this.

Customer GetCustomer (Customer customer) 
{	
	string key = $"Customer:CustomerID:{customer.customerID}"; 
	//Check data in NCache first
	Customer customer = _NCacheClient.Get<Customer>(key);

	if (customer != null) 
	{
		return customer;
	}
	//If data is not in NCache then get from Cosmos DB and Cache it
	else
	{
		ResourceResponse<Document> response =
		_CosmosDbClient.ReadDocumentAsync(UriFactory.CreateDocumentUri (DatabaseId,CollectionId,key)).Result;
		customer = (Customer)(dynamic)response.Resource;
		_NCacheClient.Insert(key, customer);
		return customer;

I'm not going to show add at this point because that's already very simple one. So, I'm going to hit play, I hit this break point and before I do this, make changes. I'm going to go ahead and clear the contents. So, that I start fresh. Okay. So, contents are zero on both servers. That's what is expected. So, let's hit this. It’s in the break point, right. So, you would notice quickly that it's expecting me to fetch a customer ALFAKI and based on that, if I keep hitting this for the first time, it will construct a customer key. That's the key that we're dealing with and I would try to fetch it from the cache and obviously, it would find null because it's a fresh start.

On a null, it would fetch it from the Cosmos DB and then it would add it into the cache as well and you can see one item added and next thing is, it would just retrieve and display the value on the screen as well and if I run this one more time, it's expecting the same customer from the cache this time because now it's cached and each time you would go ahead and you can also specify all sort of TTL, all sort of properties that you have in the Cosmo DB as well and you get the customer from the cache as well. Exact same customer and this time, it would not go to the Cosmos DB and it would just show you this on the screen as well.

So, it's a simple hello world program, getting the same values from the cache because now, it's cached and that's how you would and it's a lot more faster. You can run a side-by-side comparison test between Cosmos DB and NCache and you can see NCache is a lot more faster and you can also save trips to the Cosmos DB and that would impact the cost factor as well. It would just reduce it. So, that's the first use case.

Second use case is how to manage collections and there are two options here. You have entire collection as one item or you can cache each collection item separately as well. So, for that you can, first of all, go through five and if I show you the code here, you can just store a list as a single item. So, I would just hit a breakpoint here. This is not expecting anything, I would just show you getting it from the cache and then hitting the play button right away.

Ron, I have a question for you. Is there any SQL type search option available or any other sort of special features? Yes, that's a very good question. This is a basic API that I'm showing. NCache also has a mechanism of using tags. You can also use the SQL search, you can use LINQ, we also have Full Text Search available as well. So, it's very comparable. If you guys are familiar with SQL you can use SQL API of NCache. It's called Object Query Language. If you guys are familiar with LINQ and that's what you prefer you can fetch items based on the LINQ and then Full Text Search is another feature. We're showing a key value pair for the sake of simplicity. But like I said these are all the options that you can utilize as part of it as well.

So, first time it gets a null value again and then if I hit play, I should have this customer loaded as a single item in the cache. Only one item is loaded. If I run this one more time, without stopping anything, it brings me in this customer collection from the cache this time. So, we have 98 list elements but this is a customer list of customers as a single item store. So, this is one option. If you're interested in result set caching, you can cache entire collection as one item and you know for sure that this is the collection, that you need all the time and you don't need any other list members or the result set that you're interested in to storing them as one item doesn't hurt. But it's mostly recommended for smaller collections and also for result set caching.

Second and most preferred approach would be cache each collection item separately as well. So, you get a query executed, API executed against Cosmos DB, get a bunch of documents, iterate through those documents and store them individually and then logically group them with the help of a tag. So, for example, we're doing this right here.

void GetCustomersByCity (string country) 
{
    //Retrieve all customers from NCache first
    List<Customer> customers = new List<Customer>();
    var tagByCountry = new Tag($"Customer:Country:{country}");
    IDictionary<string, Customer> items = _NCacheClient.SearchService.GetByTags<Customer>(new[]{tagByCountry},
    TagSearchOptions.ByAnyTag);
    
    //If data is not in NCache then get from Cosmos DB and Cache it
    if (items != null && items.Count > 0)
    {
    IDocumentQuery<Customer> query = _CosmosDbClient.CreateDocumentQuery<Customer>(
    UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), new FeedOptions { MaxItemCount = -1,
    EnableCrossPartitionQuery=true }).Where(c => c.Country == country
    ).AsDocumentQuery();

If I show you the code, for example, this is the test case right here. Enter the name of the country, some checks based on that it would construct the list and it also constructs a tag by country with the runtime parameter country and then it calls “_cache.SearchService” and as part of search service we also have OQL. We also have continuous query, we also have LINQ and we have some other searching mechanism that you can use. But I'm using get by tag.

So, it's expecting that it already cached individually and all those individual items are not a list but you can put them in a collection using a tag. So, using that tag you can get the entire collection back. For the first time, it would check in the cache, if it finds it returns, if it doesn't, it would go to the Cosmo DB, execute the query and then iterate through individual customer items for each customer. Construct the cache item and also attach tag to individual items and based on that, it would store them in NCache as well using cache.InsertBulk and if I bring right here, the case number six right here. It's calling collection, creating a cache item list and cache.InsertBulk.

So, let's run this one more time. If I provide you choice number six, in this case, let me show you the cache count as well too and this time, it would just go ahead and expect a country name, let's say UK, based on that first time, it would just construct the list. List would be empty because its first iteration and then it would execute the Cosmos DB and then construct a cache item, iterate through all those. Let's see how many. I think eight to ten and it inserted in the cache as well and you can see six and plus three. So, about six items, I think seven items are added individually but with a group called tag by country, with that tag which is tagged by country, which is a runtime parameter country, which is a runtime and it has this format for that matter and if I run this one more time, which means I entered this core block one more time. I should be able to get all of them using the tag that I've just talked about. All right. And this time, I'm expecting to get all these individual items, although stored individually but categorized with a tag, decorated with the tag. So, that tag should bring me all those seven items back as a collection, right. So, it returns a list of customers as part of that. So, it's IDictionary of customers and then you can iterate through them and if I hit play, I get the exact same response from the cache as well and again, NCache is going to be, this is huge improvement in terms of performance, in terms of footprint, even for seven request units. For this sample application think of it with millions of documents, with millions of requests coming in and out. So, that's how you would manage collections and storing them as a single item as a collection, whole or each collection items separately in the cache.

Caching of Update Operations with Azure Cosmos DB

Next, we have update operations with Azure Cosmos DB. These are very simple, each time you need to add some documents, you can call cache.add on the same lines. I'm just going to show you these to save some time. So, you construct up a document, “CreateDocumentAsync” in the Cosmo DB and then call cache.Insert. So, you add in the database, add in the cache as well and for update, you can always update in the cache, in the Cosmos DB and then also in the cache as well and delete is very simple as well. You remove from the Cosmos DB using “DeleteDocumentAsync” and then you call “cache.remove” as well. So, this should complete and we have these examples lined up. So, if there are any questions otherwise, I'm going to move on to our next segment which is synchronization and that's going to take some time as well. So, please let me know, if there’re any questions otherwise I'm going to cover syncing NCache with Azure Cosmos DB. Ron we're doing good on questions. I think you have done a great job presenting the product. If any questions come, I will definitely throw at you.

Sync NCache with Azure Cosmos DB

OK. Synchronization is a big aspect. When you have data existing in two different places, in cache and the database and that's what we advocated as well, that you should use cache in combination to Cosmos DB. Each time there's a change in the cache, you also apply that change in the database. There is an update, apply that update. Delete, apply that delete. But what happens if data changes directly in Cosmos DB and that's going to be the most natural scenario where Cosmos DB may be getting updated by another application, another connector and data is being ingested by another source and your application is only reading that data and although data being updated by your application is being updated in the Cosmos DB as well but for other applications, that's a data change directly in Cosmos DB.

So, what if I have cached something. Let's assume this and I make a change in the Cosmos DB and that change is made in the Cosmos DB right here. But that change is not going to be reflected in the cache because data exists in two different places and these two sources go out of sync. So, you need to have some kind of synchronization between Azure Cosmos DB and NCache and concept that we were using here is based on Microsoft Azure change feed processing. So, we have a change feed mechanism and based on that we have two different options that you can try.

One is an Azure function with Cosmos DB trigger. So, it is an implicit change feed processing. So, it0 does a lot of back work for you and it manages add and updates to start off and you can come up with a workaround for delete. Microsoft claims it to be soft delete. So, you can use a soft delete approach, that's essentially an update but with the time to live attach to it, with some keyword attached to it, you can use within your application some keyword and you can get notified that this item is no more going to be in Cosmos DB.

Second option is the explicit implementation of change feed processors. You implement this interface yourself instead of using a Cosmos DB trigger in Azure function. I have both examples lined up. So, first let's focus on Azure function.

Azure Function DB Trigger

So, with Azure function DB trigger, this is a very simple diagram.

operations

Again, your Cosmos DB is right here, NCache is right here. Your application is using NCache and Cosmos DB or somewhere here. What if there is a document which gets added, updated or deleted? So, Microsoft Azure would, you can implement a change feed and you can base a processor on top of it. So, this change feed manages add and update events. Delete is not supported as yet by Microsoft Azure Cosmos DB and you can implement Azure function with DB trigger. That can add and update those changes in any source like NCache and I have an implementation, where I'm making NCache add, update and delete command. Soft delete, which we'll cover right away.

So, this is the overall implementation. What will happen after this demo is that each time you add a document in Cosmos DB that would automatically reflect in NCache. If there is an update in Cosmos DB that would automatically reflect in NCache and similarly, if there's a delete, we have a management for delete as well. So, you would have these two sources 100% synchronized with one another and this would ensure that there is no data inconsistency issues and that could be a big problem for applications, which need data to be in consistent form that need up-to-date data and that's a mission-critical data and very sensitive data as well. So, that's the solution that we are presenting for that.

So, first of all let me show you the Azure function right here with DB trigger.

[FunctionName("AzureFunction1")]
	public static void Run([CosmosDBTrigger(
	databaseName: "CosmosDbNCacheDemo",collectionName: "Customers",
	ConnectionStringSetting = "CosmosDbConnection",
	LeaseCollectionPrefix ="NCache-CosmosDbTrigger-",
	LeaseCollectionName = "leases")]IReadOnlyList<Document> documents,
	ILogger log)
{
	using (var cache = CacheManager.GetCache("myCache"))
	{	
		Customer customer = null;
		foreach (var document in documents)
		{
			customer = new Customer{Address =
			document.GetPropertyValue<string>("Address"),
			City = document.GetPropertyValue<string>("City"),
			CompanyName =document.GetPropertyValue<string>("CompanyName"),
			ContactName =document.GetPropertyValue<string>("ContactName"),
			Country = document.GetPropertyValue<string>("Country"),
			CustomerID = document.GetPropertyValue<string>("CustomerID")
		};

So, it takes again the cache name and this is an implementation. It has a Cosmos DB trigger. Let me just take you right here. So, you can see that it has leases information and lease I have a document store with the name leases. You can name it anything and that allows you to have a pointer for example 158 is the last pointer. So, it has a bunch of parameters. So, chain food processor is something else but I have 158 as the last pointer. So, it keeps a track of all the updates in memory from the last time it operated. So, there is a collection of all the documents and which are added and updated from the last time that was monitoring those changes. So, it based on change feed observer pattern, which Cosmo DB consistently pushes information to and that information is kept in-memory and there's a reference to that in Cosmos DB as well.

So, here is the sample implementation for this. If I bring back the Azure function. So, it needs this Cosmos DB trigger. It needs the database name, of course. Collection that you're trying to monitor through change feed. Connection string as well leases collection prefix that's something, which you put within the leases document and then lease collection named leases. And then I need my cache name here as well. For example, that's the name, I'm using democache and then what it's doing is let's for every customer in this collection is going to construct that customer object and then call cache.InsertAsync. That's a task of async invocation. So, you can use that and for delete, I'll talk about it in a bit. But let's first of all review the insert part.

So, if I run this app, this is going to wait for the changes. Using that change feed mechanism and within those leases, it would wait for all the documents which are added and updated from the last time and based on that add and update, it would make an NCache API call as well. So, let me just run this. It would take some time to debug. I will be rebuilt and then after that I should be able to apply these. I have not implemented any logger for this. So, you may get some logger errors based on my sample implementation. But you can also implement some logging details alongside that. It's a complete code that I've used for my purpose. So, I can share it towards the end of the demo as well. So, that's my Azure function. Some of the parameters are missing and that's why you are getting null values but overall, it’s getting the job done for synchronization of NCache in case any changes in the Cosmos DB happen.

And in the meantime, let me just prepare my document that I'm going to change. Let's use Ross123 because that's one what we initially had created. Let's say, I would append some values. Let me see if it's running now. Yes, it's running and it's on standby mode. So, host initialized and application started. Its executing function from the last time because I was playing, making some changes as well. So, let it complete. There you go. It's taking care of Ross123 which I updated. So, that leases document got updated.

So, let me just go ahead and clear the contents of the cache one more time and then start over. So, we have zero items in the cache and this is in a running state. So, I'm going to keep it right here and this time, I'm going to open the Cosmos DB and I'm going to append some characters at the end of country. Let's say UK multiple times and then I'm also going to add Ross123, some random strings to the city as well and if I hit update right here, this should trigger Cosmos DB as well and you can see there you go Ross123 UK UK and Ross123 44. So, it's getting use of that lease collection and then it's going to, it's actually executed that function and what that has done is, it has added that customer right here and if I go and hit my, this application was kept running. So, if I view Ross123, I need to hit play on this because there's a debug. That's the logger that I have not implemented. This should have Ross123 444 and Ross123 with some random characters added to it. So, that's how simple it is to implement Azure function for Cosmos DB.

Ron, we have a question on Azure function and the question is, is it a must to use as an Azure function and what is the cost associated with it? Azure function is again, it's not a must, you can use the other approach as well, which I'm going to demonstrate next. You can implement an observer of change field observer yourself. That's an interface. Implement all methods and don't use Azure Cosmos DB trigger in Azure function. So, that's another option. So, it's not a must. It's not the only option. Azure function is hosted in Microsoft Azure. So, there is a cost associated with it as well. But it's minimal for that matter. It's simplistic in terms of its usage but it's not the only option.

For delete, this covers add and update. If I add a new document and that should automatically be brought here. I need to keep this running because I'm using add and update, lease collection gets updated on the same lines, but deleted is a case where Microsoft recommends that you use a soft delete and for that they recommend that you should use update as alternative and use a keyword, some random key word, for example, this is a deleted inside the document and instead of deleting in Microsoft Azure Cosmos DB you use this attribute. Any random deleted, discarded and then use a TTL and then update it. And based on that if I run this one more time and show you the code as well by the way. What this is done, if it finds that there's a document with the property deleted, it's going to call cache or remove from it and based on that TTL it is going to get removed from the database anyway but it going to be removed from the cache right away.

So, I'm going to run this, I think it's already running, yes, it is. Although, there is an error code but that's what the logger. If I make a change here and update this document, it's going to be applied in the cache as well. Function customer Ross123 has been deleted from the cache as well. If I come right here, you can see it's not in the cache. And now, next thing is that since we have a TTL. So, after 10 seconds Ross123 should be removed from here. So, that's how Microsoft Azure recommends that you manage delete. Add and update is the only option for change feed observer at the moment. So, delete has to be soft delete and that's the workaround I would recommend as well, based on Microsoft recommendations.

Change Feed Processor

Next segment is syncing cache with Cosmos DB through change feed processor. So, there was a question, Azure function is not the only option. You can use change feed processor explicitly yourself as well and that's the IChangeFeedObserver interface that you implement. Let me show you the code for this.

namespace Microsoft.Azure.Documents.ChangeFeedProcessor.FeedProcessing
{
	public interface IChangeFeedObserver
	{
		Task CloseAsync(IChangeFeedObserverContext context,
		ChangeFeedObserverCloseReason reason);
		
		Task OpenAsync(IChangeFeedObserverContext context);
		
		Task ProcessChangesAsync(IChangeFeedObserverContext context,
		IReadOnlyList<Document> docs);
	}
}

It gives you a lot more control in comparison. For example, this is my factory, right here. So, I have implemented IChangeFeedObserverFactory. Let me show you this from here. OK, so, it has bunch of methods. I've implemented this IChangeFeedObserver. It has a method which closes the connections. It has a method which opens the collection and in that I'm initializing the cache and in closes, I'm actually calling cached.Dispose to dispose the resources and then main method is ProcessChangesAsync. So, it has IChangeFeedObserver Context, a list, cancellation token and some basic things. So, what I'm really doing here is I am getting hold of that within the documents this collection, list of documents. That’s the one which are going to be shared with me. So, I have implemented this in such a way that might ChangeFeedObserverFactory is getting me all the relevant resources and then based on that, based on all the leases information and document information I have provided, I can quickly process deleted and adds and updates. So, this time let me show you the update, add use case as well through this, then update and then delete and after that we'll conclude the demo.

So, this is an explicit implementation of IChangeFeedObserver. That's what being used by Microsoft Azure function with the help of Cosmos DB trigger. So, Cosmos DB trigger automatically implements that, which is easier but you have to have an Azure function. But what if, if your application needs to take care of it, then you can implement this yourself. So, cache has been started. Let me see if it's, actually I was using another cache. Let me search it, yes and by the way I'm giving all the details here, the Cosmo DB demo, the leases document and customers document that I want to monitor and I’m setting all these parameters right here, democache, save and run it and this time I will add a document, update it and delete in and show you that those are going to be applied in the cache accordingly.

Let me run the CRUD operation as well, so, that we have. I'm shutting down the Azure function and then I am. This is already added. OK, so, my cache right here, since it keeps a reference so, one document is already there. I want to get rid of it, so that we start fresh, once again and this time I would add something in Cosmo DB and you should be able to get it from the cache right away and you can see from here, I would just copy this. New document. Let's paste it right here. Instead of Ross123 let me just say Ron1122 and give the same fields here as well. Just updating some values because this document is already deleted, so, it doesn't matter. And, I think we're good. OK, save it. So, this document is right here Ron1122 and if I show you the change feed observer, it automatically took care of it. Now, all I have to do is, view this from the cache. First of all, it has been in the cache. So, if it is in the cache, it is going to load from the cache anyway. So, I'm going to say Ron1122 and you can see, I think I messed up the ID. It's Ron1122. There you go. So, it has the same items.

I'm going to now update it, so that we see the updated use case as well. Again, I'm going to update some characters within city. Let's say, NYK NYK and this time instead of UK, I would just say USA USA USA. So, that would apply an update and that would go to leases and based on that, that should automatically be applied. See, how instantaneously it is dealing with this. So, if I just run this one more time and give the customer ID Ron1122, you can see the updated value right here, which is with NYK NYK USA and USA.

For the delete, I again need to use the deleted, which is soft delete and for that all I have to do is add a random attribute. It will be any attribute by the way and give it some TTL as well. For example, deleted with TTL 10 that should update it but in turn, I would remove it because my code has a handling for deleted keyword and time-to-live will take care of deletion from Cosmo DB and deleted keyword as soon as I find one, I know that my application is designed in such a way that Cosmo DB is going to get rid of this document. So, I need to get rid of from the cache. So, it's a soft delete for Cosmos DB and if you notice right here, there you go. Following keys were deleted which means this is not going to exist in the cache anymore. If I had to enter item with given ID does not exist. So, it does not give you any stale data, if you use NCache with these two approaches.

So, let me quickly sum it up. Sam I would just take two more minutes. So, we initially talked about data caching, get operations. You can get started with simple APIs. As far as getting a document is concerned, call cache.Get. First check from cache, don't find it, get it from the Cosmos DB and also add it in the cache. So, that completes the cycle. Collections, cache entire collection is one item or cache each collection item separately and we talked about merits of these two approaches and then most important aspect is add, updates through this same APIs. Syncing of NCache is possible with Cosmos DB. It's pretty straight forward. We have two options, Azure function with DB trigger or IChangeFeedObserver interface implemented explicitly. So, both approaches were discussed and you can choose between these.

Towards the end, NCache is a highly available, linearly scalable, a very reliable .NET distributed cache. We have bunch of caching topologies. Client cache, WAN Replication Bridge. So, you can use it for Microsoft Azure Cosmos DB on-prem, within the cloud and also an on-prem. So, different options are available as part of that. Please, let me know if there’re any questions, as far as tech details are concerned otherwise, I would hand it over to Sam.

Ron, there is a question which we kind of touched upon but the question is, would you be more recommending, what would be more recommended option? IChangeFeed or an Azure function? You talked about it but if you want to shed some light on it. Sure, that's a debate by the way. If you want ease of use, you're more comfortable with Azure function, go with that and if you are a developer who wants to use components and keep things in control because the IChangeFeedObserver interface is something that you get full control on opening the connections, closing the connection and applying. So, if you want more control, use the IChangeFeedObserver and use the custom implementation. If you want to have ease-of-use, use Azure function with DB trigger.

OK, we got another question, is there a webinar to explain more in regards to NCache architecture and working? Yes, there is. On our recorded webinar, we have series of webinars available and one of the webinars is actually named NCache Architecture. So, you can have a look up that. And all of these are available on our website, right Ron? Yes, as a matter of fact, this recording is going to be published in next few days. OK, perfect. So, we have only one minute. So, guys thank you very much for joining everybody. I hope this was helpful. We try to answer as many questions as we could. If there are any additional questions, please reach out to support@alachisoft.com. If you want us to schedule a personalized demo, we'll be more than happy to do that for you as well. If you have any sales related questions, you can always approach our sales team at sales@alachisoft.com. With that being said, I would like to once again thank everybody for joining. Reach out to us, if you have any questions and appreciate your time. Thank you and have a great day.

What to Do Next?

 

Signup for monthly email newsletter to get latest updates.

Contact Us

PHONE

+1 (214) 764-6933 (US)

+44 20 7993 8327 (UK)

© Copyright Alachisoft 2002 - . All rights reserved.