A fundamental component of any Data Driven web or mobile application is the ability to access, manipulate and utilise data. The average application will require access data from a number of different data repositories using a number of different data access techniques.
These techniques may consist of direct database access, reading, transforming and manipulating XML, CSV, JSON and Text Files, access to SOAP and Restful web services.
Each of these data access techniques and strategies each
What is Cache Memory
Caching is a technique of storing frequently used data/ information in memory in order for the same data/information can be accessed quicker and more efficiently by accessing directly form computer memory instead of being re-generated by the application the next time it is needed.
Caching can significantly boost your application performance in ASP.net MVC applications as pages and controls are dynamically generated. It can also enhance data related transaction speeds because these are often expensive in terms of response time.
The primary purpose of caching in applications is to eliminate unnecessary requests to external data sources for data that does not change frequently or store operational user data that does not need to be persisted for future reference.
Caching provides a copy of the data and the copy is maintained for defined duration which is configured by the application
InMemory caching is a simple form of cache data stored in the memory of the local web server.
Why use Cache memory?
Enabling Cache into your application certainly does add some additional complexity and therefore most developers are weary of introducing cache into their application stack.
However, Caching does provide 3 benefits that are vitally important for the success of your website:
- Makes your site faster
- Provides a better customer experience
- Saves Money eliminating unnecessary bandwidth costs and server spend
If your web pages require database calls to render in order to get data that does not change all that often, then caching that page data will improve the response times of your page in order of magnitudes.
What should you Cache
Identifying and implementing the right caching strategy for your application is purely dependent on the needs and requirements. However, if you're after the best response possible and want to maximize the performance of your application, then it's a great idea to go for the highest level possible.
There are several different caching strategies
Browser Caching
Downloading web page assets the network is both slow and expensive. Large responses may require several roundtrips between the client and server, resulting in delays between when they are available and when the browser can process them, and also incurs data costs for the visitor.
The ability to cache and reuse previous resources is a critical aspect of optimizing for performance.
There are several limitations to browser caching :
- It's not possible to invalidate cache entries therefore you'll need to be cautious of setting cache durations
- You can't set data dependent cache
Content Delivery Network
A Content Delivery Network (CDN) works by providing alternative server nodes for users to download resources (usually static content like images and JavaScript). These nodes spread throughout the world, therefore being geographically closer to your users, ensuring a faster response and download time of content due to reduced latency.
Read more on why you should use a CDN >>
InMemory Caching
The in-memory caching system is designed to increase application performance by holding frequently-requested data in memory, reducing the need for database queries to get that data.
The caching system is optimized for use in a clustered installation, where you set up and configure a separate external cache server. In a single-machine installation, the application will use a local cache in the application's server's process, rather than a cache server.
Types of In-Memory Cache
Application server
The application manages the relationship between user requests, the near cache, the cache server, and the database.
Near cache. Each application server has its own near cache for the data most recently requested from that cluster node. The near cache is the first place the application looks, followed by the cache server, then the database.
Cache server
The cache server is installed on a machine separate from application server nodes in the cluster. It's available to all nodes in the cluster (in fact, you can't create a cluster without declaring the address of a cache server).
Local cache
The local cache exists mainly for single-machine installations, where a cache server might not be present. Like the near cache, it lives with the application server. The local cache should only be used for single-machine installations or for data that should not be available to other nodes in a cluster. An application server's local cache does not participate in synchronization across the cluster.
Clustering system
The clustering system reports near cache changes across the application server nodes. As a result, although data is not fully replicated across nodes, all nodes are aware when the content of their near caches must be updated from the cache server or the database.
What is Redis
Why is Redis popular
Redis is extremely fast, effective and simple to use. Getting started with Redis is relatively quick, and it usually takes only a few minutes to get set up and working within an application. Thus, a small investment of time and effort can have an immediate, dramatic impact on performance of the application.
How to Install Redis
There are a number of different means to install Redis depending on your Development environment and intended deployment Environment.
Windows
The Microsoft Open Tech group develops and maintains Windows port targeting Win64 available.
Download the latest .msi and install
Install via chocolatey
if you haven't installed chocolatey yet I suggest you do. If you come from a Linux environment you can think of chocolatey as a package manager for the Operating system much like apt, yum or dnf
You can also install redis using chocolatey package manager, using choco install redis-64
command.
Linux
Installing Redis on Ubuntu 16.04 is simple
Alternatively, you can build it from the source code, follow the instructions Redis.io
Mac OSX
The easiest way to install Redis on Mac OSX is via Homebrew
Docker
Check out the official Redis Docker Repository or check it out in the Docker Store.
It's also worth checking out Containers & Redis – Running Redis on Windows with Docker
Once you install redis you can run redis-server command to start the redis server.
Learning Redis
I recommend spending some time following the free Redis Tutorial - try redis and just reviewing the full list of commands available. Although as a Dotnet developer you may not need to interact directly with Redis, it's still good to understand what is happening under the hood.
Redis UI Tools
Although you can easily use the Redis-Cli to query and extract data from Redis, personally I found it quicker and easier to use GUI during development to see what is going on and check my data.
I found a couple of handy free GUI tools
- Redis Desktop Manager - Free on Windows
- Redis GUI Manager - Free on Linux & Windows
Redis Persistence
A great advantage of Redis over other InMemory Data Stores, is that Redis can actually persist it's Data to Disk, and there are 4 options to choose from:
- RDB (Redis Database File) most common option, it takes a snapshot of your database and stores it on disk in .rdb files. The snapshots can be configured to save after so many requests or at timed intervals. Useful for scheduling timed backups. Drawback of using this method is if your server goes down you should expect some data loss.
- AOF (Append Only File) - creates a store of all of the Redis Commands, when Redis restarts it executes these commands bringing the database back recent state. This is a much slower solution and the files can grow to large sizes
- RDB & AOF - A hybrid best of both worlds solution with scheduled backups from RDB and the reliability of AOF.
- Nothing - use it as a cache and rely on an alternate database for persistent data.
Using Redis in ASP.net MVC Core
Using Redis in ASP.net MVC Core is incredibily easy and you could literally be up and running with Redis in matter of minutes. In my sample project we are going to use Redis for Session Store.
In my example I created a standard ASP.net MVC Core Project. You could of course use any of the other Dotnet core project templates, as the steps for configuration and using will be exactly the same.
Once the project has been created, we will need to use Nuget to add 2 addtional packages to our project.
We're now pretty much set up to go, we can now start add some settings to our appsettings.Development.json
, these are custom configuration settings we have set them explicitly for our development machine. These settings may change for Production Environment and you will have a different appsettings
file for that environment.
We are now ready to go configure our application to use Redis for Session store. We just need to edit out Startup.cs
Then we just need to instruct our Application to use the session object.
Adding the AddDistributedCache
option enables an Interface IDistributedCache
that we can use to add and retrieve values. This also enables controller dependency injection by default, so we can make use of IDistributedCache
throughout our web application.
We have now completed most of our configuration required for using Redis. You can now add some code to the HomeController.cs
Updating your Index.cshtml
with
Then running the application it should work as expected and your application will now be using Redis for it's session store. If you we use our Redis Desktop manager to review our results in Redis Cache we'll see our results as follows.
However, you may be thinking to yourself that this is a clunky approach to interacting with the session object. This may be OK on small projects but when you start working on bigger projects or as your project grows this method is going to be become even more awkward and your code will start to look messy!
There has to be a better way! Check out my post Why, When and How to use Redis in ASP.net MVC Core for some ideas on how to include this type of functionality within your ASP.net MVC Core applications.
Redis is more than just a session cache
Redis stores data in [Key, Value] pairs, enabling the developer to use and store values in efficient ways using a number of different data structures:
- Strings
- Lists
- Hashes
- Sets
- Sorted Sets
- HyperLog
A typical web application needs to be able to store a lot more information in a session or in memory store for users. At the same time applications need to be fast and responsive.
IDistributedCache
All distributed cache implementations should adhere to the IDistributedCache
interface, which contains contracts for both Synchronous
and Asynchronous
methods. It is up to the developer to implement these methods.
For the most part we have already configured the IDistributedCache
interface in Startup.cs
. We go ahead and Dependency Inject that into our HomeController
and start using it right away.
Add the Following line code to your
IDistributedCache
has async methods, which are great as you can utlise these to interact with cache repository asynchronously which will also have speed and response improvements.
IDistributedCache
allows for storing either string values or byte values. If you want to serialize an object and store the entire thing, you can either serialize it to bytes and save it as bytes, or serialize it to JSON and save it as a string if you prefer.
More cache
Redis is great for expanding the capabilities for session store, but it's not all it can do.
What if we want to store frequently accessed but not refequently changing data. We may want to store things like json
files or even a users shopping basket in memory as they move through your website.
StackExchange Redis
We can very quickly extend our application to make full use of Redis by very quickly integrating the Stackexchange.Redis
library. We'll just quickly install the nuget package
In my sample application I have added a new class library project and called it RedisConfig
.
The StackExchange.Redis
library is a great library and simple to use as it abstracts and simplifies working with Redis making it simpler for DotNet Developers to work efficiently with Redis.
I created a RedisConnectionFactory
class which implements a very simple interface
I then registered the ConnectionFactory for Dependency Injection in the Startup.cs as singleton.
Then injected it to the controller.
We can now make use of is as follows
When we run our application we'll now see the new key being added to our Redis Cache. Our value is now accessible to all users regardless of session, so this may be a good place to store commonly accessed data, which may or may not be a good idea depending on your views and needs. However, from my experience elaborating on this approach has provided some significant performance improvements in some applications.
Obviously we don't want to be polluting our Controller methods with db.StringSet("somekey", "somevalue");
statements, we'll want to wrap this to some kind of helper or service we can inject into the controller.
We'll also possibly want to expand this is include storing of commonly accessed json
files etc.
Summary
Making use of Redis as a in memory cache repository can seriously improve the performance of your website, mobile application or even Api Service.
Redis as a caching solution has great advantages over traditional memory caching, as it persists to disk and its data is available across applications rather than a single server process.
If you've made it this far, then you certainly are ready to read my follow up Why, When and How to use Redis in ASP.net MVC Core
- What is this Directory.Packages.props file all about? - January 25, 2024
- How to add Tailwind CSS to Blazor website - November 20, 2023
- How to deploy a Blazor site to Netlify - November 17, 2023