Your official information source from the .NET Web Development and Tools group at Microsoft.
Today, we are pleased to announce a preview release of ASP.NET Session State Provider for Redis. You can use it with your own Redis server or the newly announce Microsoft Azure Redis Cache (Preview).
Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. It’s getting popular in the web development community as a session state store because of its simplicity, rich data structure support and outstanding performance.
You can download this preview release of ASP.NET session state provider for Redis (https://www.nuget.org/packages/Microsoft.Web.RedisSessionStateProvider) from NuGet gallery by running this command
Install-Package Microsoft.Web.RedisSessionStateProvider -Pre
Before using the session state provider for Redis, you need to (of course) get a Redis server. There are a lot of ways to get a Redis server depends on your OS and whether your app is in the cloud or on-prem. Today, I’m going to show you two:
The newly announced Microsoft Azure Redis Cache (Preview) provides your Redis host in Azure. It’s super easy to use. Just follow this get started article to get one in minutes. After it’s done, get hold of the host name and access key since we need to use them later.
The Redis project doesn’t directly support Windows. However, Microsoft Open Technologies, Inc. develops and maintains a high quality Windows port. You can install it from NuGet, Chocolatey or download it directly from the project github repository. After the installation, you can find the following two .exe files that we are interested at:
To get started,
When you use redis-cli.exe to connect to your Azure Redis Cache, since it doesn’t support SSL by default, the data and more importantly the access key are sent via TCP in clear text. To protect them, follow the instructions below to set up a SSL proxy on your machine for redis-cli.exe.
redis-cli.exe -p 6380 –a <your access key>
Now, you are having the TCP traffic from redis-cli.exe via a local SSL proxy provided by stunnel.
Now let’s look a little bit deeper into the settings you can use on this session state provider and how they will change its behaviors.
These are the settings that configure connections to Redis server:
When we talk to developers about the current available ASP.NET session state providers, one of the top complaints is that with the current available session state providers, if an error occurs during a session operation, the session state provider will throw an exception, which will blow up the entire application.
We want to address this in a way that it won’t surprise existing ASP.NET session state provider users and at the same time, provide the ability to opt-in the advanced behaviors. To do this, we introduced the following setting in this session state provider:
As you can see, the default behavior will still throw an exception when some error occurs. This is consistent with the other ASP.NET session state providers we provide so there won’t be any surprise and your existing code will just work.
If you set throwOnError to false, then instead of throwing an exception when some error occurs, it will fail silently. If you need to check if there was some error and if there was one, what the exception was, you can check it using this static property
This is really cool because
We also want to provide some retry logic to simplify the case where some session operation should retry on failure because of things like network glitch. At the same time, we also heard from developers that they want the ability to control the retry timeout or opt-out of retry entirely because they know retry won’t solve the issue in their cases. To do this, we introduced the following setting in this session state provider:
If you set retryTimeoutInMilliseconds to a number, say 5000, then when a session operation fails, it will retry for 5000 milliseconds before treating it as an error. So if you would like to have the session state provider to apply this retry logic for you, you can simply configure the timeout. The first retry will happen after 20 milliseconds since that is good enough in most cases when a network glitch happens. After that, it will retry every 1 second till it times out. Right after the time out, it will retry one more time to make sure that it won’t cut off the timeout by (at most) 1 second.
If you don’t think you need retry (like when you are running the Redis server on the same machine as your application) or if you want to handle the retry logic yourself, you can just leave it to the default value 0.
We are really excited about this release. Give it a try and let us know what you think!
Is this using the same "lock the session" for each request that the sql session provider does? Or will this allow more than one request to execute at the same time?
@Paul => It does same as sql session provider - lock the session for writing.
It's very great! I have some questions
How it saves items into redis? Based from HGETALL from screenshot each item saved as separate item in the same hashset? Does each item loads and serializes independently on others or all of them loaded in one request to Redis? What Redis provider it uses underhood? ServiceStack\BookSlave\ or some custom implementations?
@ Sergey Litvinov
How it saves items into redis?
=> It saves single session into Redis as single hash.
For example, I have session with sesion id = "session-id-1". I have stored "key1 = val1" and "key2=val2" inside session. If you do HGETALL session-id-1_Data you will get both keys and values.
Does each item loads and serializes independently on others or all of them loaded in one request to Redis?
=> All values for given session will be loaded during fetch cycle of session inside GetItem/GetItemExclusive using HGETALL. But they are de-serialized independently one after another. But only those which are modified will be written back during SetAndReleaseItemExclusive.
What Redis provider it uses underhood?
This is really help full. I also refer http://www.nerdcorelabs.com/ if i get any problems
It misses a simple way to share a redis cache between multiple websites. A key prefix setting in the provider could resolve this.
@Joanna Robinson: Thank you, if you need any help or have any question post here.
@styx31: Can you explain some more about what you mean by "A key prefix setting in the provider could resolve this."
Where is the source code?
@Siddharth Chatrola Currently, the provder use the session id (random chars + data) as the RedisKey in the cache.
If two websites wants to share the redis cache instance for session storage, it could be better to prefix the session id with the applicationname attribute of the provider.
See msdn.microsoft.com/.../ms178587.aspx paragraph "ApplicationName".
The ability to provide a database id could be also great.
@ styx, @styx31 = Thanks for the feedback.
I am working on following two and will publish new NuGet and will let you know configuration details.
1) RedisKey as application name + session id.
2) Ability to provide a database id.
We already have such provider here: www.nuget.org/.../RedisAspNetProviders. What is the difference?
@alex-simonov: There are many differences in actual implementation but just to mention few bigger once SSL support, throwOnError, retryTimeoutInMilliseconds etc.
@Siddharth Chatrola, where is source code hosted?
@Siddharth Chatrola, I've opened dll with Reflector and found a bug. If I modify a state of a mutable object stored in session then these changes will not be saved in redis because this provider can not track changes of state of stored mutable objects.