Some non-functional requirements from our applications are about performance and scalability. Then, we start thinking about a lot of strategies: review architecture, refactor features and algorithms, apply some caching strategy, etc.
Last days, I started using Apache Ignite as a cache strategy for some applications. Apache Ignite is an open-source In-Memory Data Grid, distributed database, caching, and high-performance computing platform.
Yeah! That’s it! All this in one solution. :D
If you want to know more about Apache Ignite, take a look at its documentation. Beyond .NET, there are samples for other programming languages as well.
This article will be split into two parts. In this first one, I will present the basic steps to work with the Cache feature and check results from a small test with that. In the second part, let’s see how can we work with SQL API feature in .NET applications.
For this test, I used the machine settings below:
- Windows 10
- Intel(R) Core(TM) i5–4440
- 16 GB RAM
- .NET 5
- Apache Ignite 2.10.0
- Docker version 20.10.6
Before implementing our cache repository, let’s run Apache Ignite with its official Docker container.
Then, run the following command to start the Apache Ignite container:
We can persist the data that will be used in the sections below in memory or on disk. For this article, the is being persisted in memory.
After running the command above, you should see the screen below:
Check if there are error messages when the Apache Ignite container has been started. If everything is OK, let’s test its Cache feature in the sections below.
The steps to use Apache Ignite are very simple. You can follow the items below to allow your application to connect with Apache Ignite.
- Add NuGet package below:
Install-Package Apache.Ignite -Version 2.10.0
- Set up a new connection with IgniteClientConfiguration class*.* in this part you need to provide at least one Apache Ignite server:
- Start a new connection with Ignition.StartClient method. This method returns an interface called IIgniteClient, which contains methods to work with cache clusters:
- With IIgniteClient.GetOrCreateCache, get or create a new cache repository to a specific object type. This method returns the ICacheClient interface, which contains methods to work with the cache repository.
Done! Now your application can perform operations in a cache repository from Apache Ignite. I recommend checking the Apache Ignite documentation to know more about available methods.
Now that we have an Apache Ignite cluster ready and the application set up appropriately, let’s test its cache feature.
For this test, two classes were created to be inserted on the Apache Ignite Cache: OrderCacheEntity (Order) and ItemCacheEntity (OrderItem).
Basically, one Order can have one or more OrderItem associated with it. Then, the next step is to generate as many Order instances as possible, adding and getting them to the cache, and finally check the performance with some counters.
The code below inserts 1 million Orders in the cache repository and checks its performance for “ICacheClient.Put” and “ICacheClient.TryGET” methods. As an attempt to create a small “workload” against the Apache Ignite container, those operations are executed with Parallel Task.
As we can see in the code above, some KPIs were created to check the performance of each operation against Apache Ignite Cache:
KPIs Operation Time:
- INPUT time (AVG seconds): the average in seconds to add an item to the cache
- OUTPUT time (AVG seconds): the average in seconds to get an item from the cache
- INPUT time (MAX seconds): the maximum time in seconds to add an item to the cache.
- OUTPUT time (MAX seconds): the maximum time in seconds to get an item from the cache.
- INPUT time (MIN seconds): the minimum time in seconds to add an item to the cache.
- OUTPUT time (MIN seconds): the minimum time in seconds to get an item from the cache.
- INPUT ERROR: number of exceptions created when the application was adding an item to the cache.
- OUTPUT ERROR: number of exceptions created when the application was getting an item from the cache.
- ITEMS CREATED: how many items were created in the cache.
- ITEMS RECEIVED: how many items were got from the cache.
- ITEMS MISSING: how many items were not in the cache.
After running the application test, the metrics below were collected:
In general, the Apache Ignite presented a nice performance adding and getting objects. The average time to add items in the cache was 0.016 seconds and 0.025 seconds to get those items from the cache. Also, there were no exceptions and lost items in this test.
Checking the Apache Ignite container, the memory consumption increase by about 390 MB, which represents about 130% more than its initial state:
- Container stats (initial state)
- Container stats (after running application test)
For now, that’s all. In the second part, let's see how can we implement the SQL API feature in our .NET applications. From a development perspective, I think that this feature from Apache Ignite is the most interesting so far.
I hope that this can be helpful for you!