In the second blog post series “Redis for .NET Developer” I will show how we will use C# to connect to Redis.
If you want to learn how to install Redis, visit my previous post on Intro to Redis for .NET Developers – Installing Redis on Windows.
We will be using StackExchange.Redis library to connect to Redis. One can download StackExchange. Redis through NuGet.
For .NET Framework
1. Let’s Download our Nuget package, you can use the command line like below or use Visual Studio (I am using VS2018).
1 |
PM> Install-Package StackExchange.Redis.StrongName |
Search for redis in your nuget window.
Once installed you will see in your output windows.
Now that the nuget package is installed, we can build a C# console app that will connect to your redis server.
Below is a sample code to connect to localhost of your redis.
1 2 3 4 5 6 7 8 9 10 |
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); if(db.StringSet("testKey", "testValue")) { var val = db.StringGet("testKey"); Console.WriteLine(val); } |
The above code will allow you to connect to Redis and store a string key “testKey” with a value of “testValue”.
For better modulation of Redis it is recommended to store ConnectionMultiplexer as a static singleton in your application.
Below is example of a RedisStore that stores the ConnectionMultiplexer as a static Lazy loaded singleton.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class RedisStore { private static readonly Lazy<ConnectionMultiplexer> LazyConnection; static RedisStore() { var configurationOptions = new ConfigurationOptions { EndPoints = { "localhost" } }; LazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(configurationOptions)); } public static ConnectionMultiplexer Connection => LazyConnection.Value; public static IDatabase RedisCache => Connection.GetDatabase(); } |
Now our previous code would something like
1 2 3 4 5 6 7 8 |
var redis = RedisStore.RedisCache; if(redis.StringSet("testKey", "testValue")) { var val = redis.StringGet("testKey"); Console.WriteLine(val); } |
Dotnet Core Version for Connection
Lets go through the process of creating a dotnet core console application.
1 2 |
$mkdir RedisConnectionDotNetCore $dotnet new console |
We will now need to install all the packages that we require to run dotnetcore with Redis.
1 2 3 4 |
$dotnet add package Microsoft.Extensions.Configuration $dotnet add package Microsoft.Extensions.Configuration.FileExtensions $dotnet add package Microsoft.Extensions.Configuration.Json $dotnet add package StackExchange.Redis --version 2.0.519 |
We will create an appsettings.json file to store our connection information, that is one of the reason we have installed all those packages into our project.
This is how my appsettings.json looks like, with only one key and value.
1 2 3 |
{ "redis.connection" :"localhost:32768" } |
We also need to tell our csproj about the output of the json file by modifying our RedisConnectionDotNetCore.csproj, we will add into our ItemGroup
1 2 3 4 5 6 7 8 9 |
<ItemGroup> <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" /> <PackageReference Include="StackExchange.Redis" Version="2.0.519" /> <None Update="appsettings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> |
Lets modify our code in RedisStore.cs such that it can read from the json file, as you can see most of the code remains the same except for where we pick our configuration from.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class RedisStore { private static readonly Lazy<ConnectionMultiplexer> LazyConnection; static RedisStore() { var builder = new ConfigurationBuilder() .SetBasePath(System.IO.Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) .Build(); var configurationOptions = new ConfigurationOptions { EndPoints = { config["redis.connection"] } }; LazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(configurationOptions)); } public static ConnectionMultiplexer Connection => LazyConnection.Value; public static IDatabase RedisCache => Connection.GetDatabase(); } |
Our Program.cs remains the same
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Program { static void Main(string[] args) { var redis = RedisStore.RedisCache; if (redis.StringSet("testKey", "testValue")) { var val = redis.StringGet("testKey"); Console.WriteLine(val); } Console.ReadKey(); } } |
Now we can run with dotnet command line
1 2 3 |
$dotnet restore $dotnet run testValue //output vaule |
In my next blog post I will cover the data structures that Redis provides.
For code please visit https://github.com/taswar/RedisForNetDevelopers
For previous Redis topics
it is a nice blog , how can we use connection multiplexer for asp.net session
There are multiple ways, if you are using an IoC container you can just get it from the Dependency Injection IoC container.
If you are not then you can use a static class with static property.
Something like this.
public static class GlobalVariables
{
public static string MyGlobalVariable { get; set; }
}
or even use the ASP.NET Application object.
Application[“GlobalValueKey”] = connection;
is ConnectionMultiplexer as a static Lazy loaded singleton a good technical for asp.net mvc web app?
What is different from
var redis = ConnectionMultiplexer.Connect(“localhost”);
var redisDb = redis.GetDatabase();
The advantage of Lazy loading is that it will only be called once when in use, since you may also have redis running in remote servers, thus it would make sense in asp.net mvc app to place it in the Global.ascx file.
Other Advantages
– Minimizes start up time of your web app.
– Application consumes less memory because of on-demand loading.
– Unnecessary redis calls is avoided
The Multiplexer does quite a few things, it was designed to be shared and reused between caller, it is fully thread-safe.
You should not create a ConnectionMultiplexer per operation thus using the lazy loaded into a singleton, even though the Connection Multiplexer implements IDisposable one should reuse it as much as possible.
The ConnectionMultiplexer has also master/slave setup, so you can say something like ConectionMultiplexer(server-master:1234, server-slave:2345);
Think of the ConnectionMultiplexer as a connection in SQLServer, and in order to use the database which is an IDatabase you will need to call GetDatabase() like your second call.
Hope this explains it for you 🙂
Hi I want to connect with a remote located Redis using C#.net.Could you suggest steps for connecting of it.Which means my dot net code is running in different server redis is in different server.
Hi Taswar, I had used StackExchange library to connect and work with redis but because of some performance issue I moved to ServiceStack.Redis library. It is working absolutely fine.Now my requirement is, I want to set Redis Sentinel for Redia HA and also I want to redirect all reading connection to slave and writing connections to master. Is it possible to do it? I have read at Redis.io that redis allows us to open read from slave master connection but I am not able to find its equivalent in .Net library. Can u please help?
the code would be the same, you just need to change the connection string in the app to use the remote ip address
EndPoints = { “10.10.1.278” } whatever the ip address is.
Take a look at the code in app.config where I have the redis.connection
https://github.com/taswar/RedisForNetDevelopers/blob/master/9.RedisPubSub/RedisPubSub/App.config
you just need to modify the ip address
You may want to take a look at some of the sentinel support in the test cases of stackexchange.
https://github.com/StackExchange/StackExchange.Redis/blob/master/StackExchange.Redis.Tests/Sentinel.cs
You can also find out if a server is a slave in redis stack exchange the server has a method called IsSlave. Check out the test cases in
https://github.com/StackExchange/StackExchange.Redis/blob/master/StackExchange.Redis.Tests/Cluster.cs
Sorry I have not played much with ServiceStack library as of yet 🙁
Taswar – I was reading in the StackExchange.Redis docs that unlike the ConnectionMultiplexer, the object returned from GetDatabase() “…is a cheap pass-thru object, and does not need to be stored.” However as a member of your RedisStore singleton you’ve got:
public static IDatabase RedisCache => Connection.GetDatabase();
which reuses this object. Thoughts?
Yes the GetDatabase is definitely a cheap object to reuse, but if you look above the connection which is the lazy ConnectionMultiplexer that is wrapped around, that is the thing that I wanted to create only once. Also by not using an IOC container, did not want to over complicate the code base.
The connection to the Redis Cache is managed by the ConnectionMultiplexer class. This class is designed to be shared and reused throughout your client application, and does not need to be created on a per operation basis.
Now I was also lazy *pun intended* and did not want to call GetDatabase every time thus I made a helper method just to get RedisCache, rather than calling GetDatabase in each of the calls 🙂
Hi,
I have done the setup for redis in AWS console and i am using the same code of your .
but now i am not able to connect to my AWS redis url from my code.
can you suggest how to connect it ?
Thanks
Are you connecting to the right url and port? and is your port open in aws, you may want to check if it is exposed to public internet or at least to your network.
Try telnet to the port first to test it out.
something like telnet mycachecluster.eaogs8.0001.usw2.cache.amazonaws.com 11211
Hi,
I would like to understand the licensing details if I am using the StackExchange.redis in my product.based on my readings it is opensource and free to use.
could you please let me know more details o the same.
Also, I have a scenario where I need to update the Redis cache from my SQL tables.
The data need to be sync always with SQL and Redis.
Is there any possibility to achieve the same.
Narayanan K
The license of the library is in MIT, so you can use it in commercial software. Please note I am not the author of StackExchange Redis, you may want to also look at their license in their github source code.
For your second question please look at the design pattern called Cache Aside pattern that will help you keep things in sync with your sql tables and redis. You will need to write custom code for that.
Hello Taswar, Hope you’re keeping well.
I’m a completely new and a noob to Redis. Your blogs has really helped out to try out the implementation of Redis. Learned basics of Redis through all your blogs. Currently i’ve been facing issues, i’ve been trying to implement the same concept of this blog in dotnet core webapi. i want to read the redis connection from appsettings.json and want to set and get values from Controller. I’m not able to establish the connection with Redis Server. Can you please help me with how to get this thing fixed? A small example of how to import connection in startup.cs from appsettings.json and accessing this connection in controllers to set and get values would really help me.
Thanks
Regards.
-Shubham
Sure let me take a look at what I can do and will update you 🙂
Take a look at my sample https://github.com/taswar/RedisForNetDevelopers/tree/master/14.RedisAspDotNetCore/RedisAspDotNetCoreWebApiSample
I will add another blog later today to explain more in details.
Hi Taswar,
Wondering if you are able to give me some pointers where i could be wrong. My environment is i have 3 VMs and on each VM i have created 1 Master and 1 Slave (as per min requirement for a cluster). All works well except when i test it by failing over one of the master then while using the Stackoverflow.Redis it says “Cluster Down”. I have built the cluster at least 3 times from scratch but nothing seem to work differently.
Hopefully you can give me some pointers on this.
(PS: I am using .Net Framework 4.7.1)
what happens when you use redis cli? does your slave become master? I would first figure out if the slave is promoted to master before relying on stack overflow redis. Make sure you can connect via cli then take a look at the code.
Here is a blog that might help https://rtfm.co.ua/en/redis-replication-part-2-master-slave-replication-and-redis-sentinel/
Hello Taswar,
My requirement is like I have 2 lua script files which has got alogirthm, now I want to load this to redis server and execute this in evalsha(evalsha is the method which is used in Java) similarly in .Net something should be there right like evalsha..
Can you help on how can I proceed.
1.establish connection, so here I need to establish lazy connection or normal connection?
2.then do I need to use redisstore and redis store server?
How can I acheieve it.
in Java the code is something like this.
I want to acheieve it in .Net
public void putTask(Customer customer, Task task) {
syncCommands.evalsha(putTaskShaDigest, ScriptOutputType.INTEGER, keys, customer.getId(), String.valueOf(customer.getLevel()), task.getId(), String.valueOf(task.getPriority()));
}
public String takeNextTask() {
return syncCommands.evalsha(nextTaskShaDigest, ScriptOutputType.VALUE, keys);
}
Did you get a chance to read my post on lua scripting?
http://taswar.zeytinsoft.com/redis-lua-scripting/