The recently publicly previewed Azure Redis cache is easily integrated into your Azure Web site application, where I integrate the MVC Movie sample program into Azure Redis cache and deploy it to azure Web services (Websites), about a few About 15 minutes.
After importing cache, the speed of the program is nearly 100 times times faster than the pure database, because the data can be accessed directly from the cache, without having to go to the database to catch the data, so you can also reduce the number of accesses to the database, so that the action of the data query become faster.
Next I'll explain how I've integrated Azure redis Cache into my asp.net MVC Movie paradigm.
In the preview of the new Azure management interface, we can build a new Redis Cache service as shown in the picture.
It would take about 15 minutes to set up the Cache, but at the same time I would not be waiting here, but would modify my program. If you need a complete reference manual, you can refer to the use of the Redis cache for the article, but remember that Redis cache service must be in the same data center as your Web service, different data centers may vary by about 25 times times, The steps can be set up to refer to create a Redis Cache page, you can download the original Mvcmovie sample process to change, or directly download my modified example, but remember to modify the Cache service URL and authentication data will work properly.
When the cache service is set up, write down the cache name like <yourname>.redis.cache.windows.net and password (click the Keys button to get the name and password).
In your MVC project, use the NuGet Suite management tool to install the Stackexchange.redis kit, which is already installed and referenced in the project if you are downloading a modified example.
Open the Update-database directive in the Suite Management Console (Package Manager console).
Add the program code that links the cache service to the associated controller:
public class Moviescontroller:controller
{
Private Moviedbcontext db = Newmoviedbcontext ();
private static connectionmultiplexer connection;
private static Connectionmultiplexer Connection
{
Get
{
if (connection = null | |!connection. isconnected)
{
Connection = Connectionmultiplexer.connect (
". Redis.cache.windows.net,ssl=true," +
"password=");
}
return connection;
}
}
Note: Generally it is not recommended that you write the account password data directly in the program code, here only to facilitate understanding of the program code to do so. Refer to the methods described in this article by Windows Azure Web sites:how creator Strings and Connection Strings Work to process account passwords for sensitive data.
In the above program code, I've already stored the link to the cache as a static member, so you don't have to re-establish a link to the cache at every request, you just need to check to see if the link is still there, and if you've lost the link, then reconnect.
Add a new category and include this samplestackexchangeredisextension category:
public static Class Samplestackexchangeredisextensions
{
public static T get<t> (this idatabase cache, string key)
{
Return deserialize<t> (cache. Stringget (key));
}
public static object Get (this idatabase cache, string key)
{
Return deserialize<object> (cache. Stringget (key));
}
public static void Set (this idatabase cache, string key, Object value)
{
Cache. Stringset (Key, Serialize (value));
}
Static byte] Serialize (object o)
{
if (o = = null)
{
return null;
}
BinaryFormatter BinaryFormatter = new BinaryFormatter ();
using (MemoryStream MemoryStream = new MemoryStream ())
{
Binaryformatter.serialize (MemoryStream, O);
BYTE] Objectdataasstream = Memorystream.toarray ();
return objectdataasstream;
}
}
Static T deserialize<t> (byte] stream)
{
BinaryFormatter BinaryFormatter = new BinaryFormatter ();
if (stream = = null)
return default (T);
using (MemoryStream MemoryStream = new MemoryStream (stream))
{
T result = (t) binaryformatter.deserialize (MemoryStream);
return result;
}
}
}
The Samplestackexchangeredisextensions category allows you to easily make any serializable (serializable) categories available for quick access. You can add the [Serializable] attribute to your model.
[Serializable]
public class Movie
Then all Movie Movie = db. Movies.find (ID); are modified to:
Movie Movie = db. Movies.find (ID);
Movie Movie = getmovie (int) ID);
In the Edit and Delete methods of the POST call, remember to clear the cache.
Clearmoviecache (movie.id);
Add the following code to the controller, where Getmovie is a very standard cache operation:
Movie getmovie (int id)
{
stopwatch SW = Stopwatch.startnew ();
Idatabase cache = Connection.getdatabase ();
Movie m = (Movie) cache. Get (ID. ToString ());
if (M = = null)
{
Movie Movie = db. Movies.find (ID);
Cache. Set (ID. ToString (), movie);
Stopwatchmiss (SW);
return movie;
}
Stopwatchhit (SW);
return m;
}
private void Clearmoviecache (int p)
{
Idatabase cache = connection. Getdatabase ();
If cache. Keyexists (p.tostring ())
Cache. Keydelete (P.tostring ());
}
void Stopwatchend (stopwatch sw, String msg)
{
Sw. Stop ();
Double ms = SW. Elapsedticks/(Stopwatch.frequency/(1000.0));
viewbag.cachemsg = msg + Ms. ToString () +
"PID:" + process.getcurrentprocess (). Id.tostring ();
}
void Stopwatchmiss (stopwatch sw)
{
Stopwatchend (SW, "Miss–ms:");
}
void Stopwatchhit (stopwatch sw)
{
Stopwatchend (SW, "Hit–ms:");
}
In addition, add the VIEWBAG.CACHEMSG program code to the views\shared\_layout.cshtml file to display the cache information on the page.
<div class= "Container body-content" >
@RenderBody ()
<hr/>
<footer>
<h2> @ViewBag .cachemsg</h2>
</footer>
</div>
@Scripts. Render ("~/bundles/jquery")
@Scripts. Render ("~/bundles/bootstrap")
@RenderSection ("Scripts", Required:false)
</body>
</html>
Now you can test the effect of the cache in the development environment, but if your database is small and the cache is in the cloud, the effect may not be obvious and the deployment to Azure should feel a noticeable difference.
Monitor the cache service in the management interface
In the admin interface, you can see the HIT/MISS statistics for the cache:
You can add other relevant information to monitor, such as custom time range, cleared key value, expired key value, CPU or memory used, etc.
Of course, you can also add alert notification (add alert) to help you monitor the usage of the cache, as in the following figure I added a warning notice that in 15 minutes, when the number of key values cleared is too high, you may want to use a larger cache.
Deploying a Web site to Azure from Visual Studio is easy, as long as you right-click on a Web project and choose to publish it again, reminding that the Web service must be in the same data center as the cache service, otherwise the delay in network transmission will drag down the efficiency of the cache. And don't forget to check Execute Code migrations on release.
Once the deployment is complete, you can try to see if there is a significant difference in the efficiency of the cache.
Pressure Test quick-access Service
The preset cache time is 1000ms (1 seconds), and you can try using the following code to change time out (Force clear cache) to longer or shorter periods, and test your cache service for normal. When #define NOTTESTINGTIMEOUT The code is annotated, the timeout is set to 150ms, allowing the cache to be cleared in a short time.
#else
#region Stresstest
private static Connectionmultiplexer Connection
{
Get
{
if (connection!= null && connection. isconnected)
{
return connection;
}
var config = new configurationoptions ();
Config. Endpoints.add (Keys.url);
Config. Password = keys.passwd;
Config. SSL = true;
Config. Synctimeout = 150;
Connection = connectionmultiplexer.connect (config);
return connection;
}
}
#endregion
#endif
In the stress test, it is best to close the session cache, the simple way is to the Web.config file in the entire application of the session cache close.
<sessionstate mode= "Off"/>
or use [sessionstate (sessionstatebehavior.disabled)] in your controller. The following updated Getmovie method can work more stably because it will be retried 3 times when the time out exception occurs.
Movie getmovie (int id, int retryattempts = 0)
{
Idatabase cache = Connection.getdatabase ();
if (RetryAttempts > 3)
{
String error = "Getmovie timeout with" + retryattempts.tostring ()
+ "retry attempts." Movie id = "+ ID. ToString ();
Logger (Error);
viewbag.cachemsg = error + "Fetch from DB";
Cache unavailable, get data from DB
Return DB. Movies.find (ID);
}
stopwatch SW = Stopwatch.startnew ();
Movie m;
Try
{
m = (Movie) cache. Get (ID. ToString ());
}
catch (timeoutexception tx)
{
Logger ("Getmovie fail, id =" + ID. ToString (), TX);
return Getmovie (ID, ++retryattempts);
}
if (M = = null)
{
Movie Movie = db. Movies.find (ID);
Cache. Set (ID. ToString (), movie);
Stopwatchmiss (SW);
return movie;
}
Stopwatchhit (SW);
return m;
}
There are many ways to test the cache service in this sample program.
Like the Writecache or Readcache method will preset to write or read 1,000 of data, you can add "n" after the URL to make them read and write n * 1000 pen data, as shown in the example above Http://<your site> AZUREWEBSITES.NET/MOVIES/READCACHE/3 will read 3,000 of the cache data.
In this 150ms timeout environment, my program will be very easy to run into the timeout situation to access the database, because my program has the correct handling of this timeout exception to be able to read the database smoothly. So it is recommended that your online application should be able to handle this exception, because depending on the level of service on the cloud platform, if you choose a basic solution, there may be a few minutes of inaccessible (such as updating the VM) in one months, unless you choose a standard solution and build a Master-slave architecture backup, However, it is recommended that you address this possible exception in your program code.
Azure Redis Cache (Preview) asp.net session state Provider
asp.net the default as session state Provider cannot be used by multiple site entities at the same time, while SQL Server session state can allow different Web sites to use the same session state at the same time. However, this is limited by the latency of database queries, which in turn affects performance. The Redis session of the state cache provider is another option, if your site will only use not very large sessions state, you can use the Redis cache to quickly take these sessions state data.
You can refer to this article, add Redissessionstateprovider to your Web application, and then modify the Web.config file to set the Redis Cache service:
<system.web>
<customerrors mode= "Off"/>
<!--<sessionstate mode= "Off"/>-->
<authentication mode= "None"/>
<compilation debug= "true" targetframework= "4.5"/>
<httpruntime targetframework= "4.5"/>
<sessionstate mode= "Custom" customprovider= "Redissessionprovider" >
<add name= "Redissessionprovider"
Type= "Microsoft.Web.Redis.RedisSessionStateProvider"
Port= "6380"
Host= "Movie2.redis.cache.windows.net"
accesskey= "m7pnv60crvkplqmuxosc3dse6kx9nq6jp5del8tmadk="
Ssl= "true"/>
<!--<add name= "Mysessionstatestore" type= "Microsoft.Web.Redis.RedisSessionStateProvider" host= "127.0.0.1" Accesskey= "" Ssl= false/>-->
</providers>
</sessionState>
</system.web>
<system.webServer>
This way you can use the Redis Cache in your Web application to process session state. The test method is also provided in the sample program, which you can access through Http://<your Site>.azurewebsites.net/sessiontest/writesession/hello_joe, so that the Hello_joe "Write session state, you can try adding a Web service entity to see if the sessions state will be shared among multiple entities.