Shaun Xu

The Sheep-Pen of the Shaun


News

logo

Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years experience in .NET. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Aliyun) as well as WCF and ASP.NET MVC. Recently he's falling in love with JavaScript and Node.js.

Currently Shaun is working at IGT Technology Development (Beijing) Co., Ltd. as the architect responsible for product framework design and development.

MVP

My Stats

  • Posts - 94
  • Comments - 335
  • Trackbacks - 0

Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories



In the TechED North America Microsoft announced another cache service in Azure which is the Redis Cache Service. This is the 4th cache service Microsoft introduced in Azure. The first one is Shared Cache which is going to be retired in Sep as it has very critical performance issue. The second one is In-Role Cache, which is built on top of AppFabric engine, is high performance and dedicates to the role instances in the same cloud service. The third one is Managed Cache, which is based on AppFabric as well, but can be widely used by cloud service roles, virtual machines and web sites. And now we have another choice.

 

Create Redis Cache Service

Currently the Redis Cache can only be created from the new portal. Click "New" button and select "Redis Cache (Preview)" item.

01

Then I need to specify the endpoint and select a pricing tier. Currently there are 2 tiers available, basic and standard and each of them has 1GB and 250MB size sub-tiers. The different between basic and standard is that basic does support replication and SLA.

02

Next, select a resource group and the location where my Redis will be provisioned. As you can see currently there are only four regions I can select.

03

Finally click "Create" button, Microsoft Azure will start to provision a new Redis service to me. This took about 5 minutes which I'm not sure if it's normal, since other provision operations in Microsoft Azure are more faster.

04

When the Redis created I can view the status from "Browse", "Caches" menu item. As we can see the Redis endpoint and port when clicked "Properties" button. We need them when connecting to Redis from our application later.

05

Click "Key" button it will show two security keys of our Redis. We also need it to connect from our application. So we can just copy the endpoint, port and primary key in some place for later usage.

06

Now we have our Redis Cache ready and let's create an application to use it.

 

Use Redis Cache from C# (ASP.NET)

There are many client libraries for Redis where you can find here. I'd like to use the first one of C# client, which is recommended by Redis, ServiceStack.Redis. I used this library before and wrote another blog post in the April of 2012. Now let's use it again to build an ASP.NET web application in Microsoft Azure Web Site.

I created a new ASP.NET WebForm in Visual Studio. ServiceStack.Redis is available in NuGet so I can install it easily from the NuGet dialog as below. Just search for "Redis" and the first is it.

In the official document of Redis Cache, Microsoft utilizes another library to connect to Redis named "StachExchange.Redis", that can be found here. It's available in NuGet as well but still in prerelase so if you wanted to use it make sure selected "Include Prerelease" in NuGet dialog.

07

Next I changed the default page layout as below. So I can specify the key and value and press "Set" button to set it into Redis, while press "Get" value to retrieve from Redis.

   1: <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ShaunAzureRedisDemo1._Default" %>
   2:  
   3: <asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
   4:  
   5:     <div class="jumbotron">
   6:         <h1>ASP.NET</h1>
   7:         <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS, and JavaScript.</p>
   8:         <p><a href="http://www.asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
   9:     </div>
  10:  
  11:     <div class="row">
  12:         <div class="col-md-4">
  13:             <h2>Set Value</h2>
  14:             <p>
  15:                 Key: <asp:TextBox ID="txtSetKey" runat="server"></asp:TextBox>
  16:             </p>
  17:             <p>
  18:                 Value: <asp:TextBox ID="txtSetValue" runat="server"></asp:TextBox>
  19:             </p>
  20:             <p>
  21:                 <asp:Button ID="btnSet" runat="server" Text="Set" OnClick="btnSet_Click" />
  22:             </p>
  23:         </div>
  24:         <div class="col-md-4">
  25:             <h2>Get Value</h2>
  26:             <p>
  27:                 Key: <asp:TextBox ID="txtGetKey" runat="server"></asp:TextBox>
  28:             </p>
  29:             <p>
  30:                 Value: <asp:TextBox ID="txtGetValue" runat="server" ReadOnly="true"></asp:TextBox>
  31:             </p>
  32:             <p>
  33:                 <asp:Button ID="btnGet" runat="server" Text="Get" OnClick="btnGet_Click" />
  34:             </p>
  35:         </div>
  36:         <div class="col-md-4">
  37:             <h2>Trace</h2>
  38:             <p>
  39:                 <asp:TextBox ID="txtTrace" runat="server" ReadOnly="true" TextMode="MultiLine" Height="200" Width="100%"></asp:TextBox>
  40:             </p>
  41:         </div>
  42:     </div>
  43:  
  44: </asp:Content>

In the backend code I initialize an instance of ServiceStack.Redis.RedisClient with the endpoint, port and password specified, which are copied from the portal.

Yes the password is the real one. Please be nice, thank you.

   1: using ServiceStack.Redis;
   2: using System;
   3: using System.Collections.Generic;
   4: using System.Linq;
   5: using System.Web;
   6: using System.Web.UI;
   7: using System.Web.UI.WebControls;
   8:  
   9: namespace ShaunAzureRedisDemo1
  10: {
  11:     public partial class _Default : Page
  12:     {
  13:         private static RedisClient _client = new RedisClient(
  14:             "shaunrediscache.redis.cache.windows.net", 
  15:             6379, 
  16:             "Kl7UaxeZiqA1QbclSsI02mDndOccxwD6AluliF1axmA=");
  17:  
  18:         protected void Page_Load(object sender, EventArgs e)
  19:         {
  20:  
  21:         }
  22:     }
  23: }

Then I implemented two button click event handlers to set and get item from Redis. The code is very simple as below.

   1: using ServiceStack.Redis;
   2: using System;
   3: using System.Collections.Generic;
   4: using System.Linq;
   5: using System.Web;
   6: using System.Web.UI;
   7: using System.Web.UI.WebControls;
   8:  
   9: namespace ShaunAzureRedisDemo1
  10: {
  11:     public partial class _Default : Page
  12:     {
  13:         private static RedisClient _client = new RedisClient(
  14:             "shaunrediscache.redis.cache.windows.net", 
  15:             6379, 
  16:             "Kl7UaxeZiqA1QbclSsI02mDndOccxwD6AluliF1axmA=");
  17:  
  18:         protected void Page_Load(object sender, EventArgs e)
  19:         {
  20:  
  21:         }
  22:  
  23:         protected void btnSet_Click(object sender, EventArgs e)
  24:         {
  25:             var key = txtSetKey.Text;
  26:             var value = txtSetValue.Text;
  27:  
  28:             try
  29:             {
  30:                 _client.SetEntry(key, value);
  31:             }
  32:             catch (Exception ex)
  33:             {
  34:                 txtTrace.Text = ex.ToString();
  35:             }
  36:         }
  37:  
  38:         protected void btnGet_Click(object sender, EventArgs e)
  39:         {
  40:             var key = txtGetKey.Text;
  41:  
  42:             try
  43:             {
  44:                 var value = _client.GetEntry(key);
  45:                 txtGetValue.Text = value;
  46:             }
  47:             catch (Exception ex)
  48:             {
  49:                 txtTrace.Text = ex.ToString();
  50:             }
  51:         }
  52:     }
  53: }

Next, I created a new Azure Web Site. Make sure I selected the same location as the Redis so that the network transaction between them is free with the best performance. Then deploy my web application to Azure and we can test the Redis. As you can see I set an item and retrieve later.

08

If I specified a key that does not exist, it will just return NULL from the library.

09

 

Connect from Other Services and Subscriptions

A Redis Cache can be connected from other Azure services and other subscriptions, through vary types of clients. As the screenshot below I created another ASP.NET and deployed in a Cloud Service Web Role. It connected to the same Redis Cache by specifying the same endpoint, port and password so that I can retrieve the item here which was saved from the Web Site previously.

10

Also I can use this Redis Cache from another subscription in Node.js application. In this case I utilized another client library named "node_redis". In the code below I created a simple web service can user can set and get item from Redis.

In order to make it easy to test, I was using HTTP GET method for both set and get item to Redis. This is NOT a good solution. In production environment you should use HTTP POST to set item into Redis.

   1: (function () {
   2:     'use strict';
   3:  
   4:     var express = require('express');
   5:     var bodyParser = require('body-parser');
   6:     var redis = require('redis');
   7:  
   8:     var app = express();
   9:     app.use(bodyParser());
  10:  
  11:     var client = redis.createClient(6379, 'shaunrediscache.redis.cache.windows.net');
  12:     client.auth('Kl7UaxeZiqA1QbclSsI02mDndOccxwD6AluliF1axmA=');
  13:  
  14:     app.get('/get/:key', function (req, res) {
  15:         var key = req.params.key;
  16:         client.get(key, function (error, reply) {
  17:             if (error) {
  18:                 res.send(500, error);
  19:             }
  20:             else {
  21:                 res.send(200, reply);
  22:             }
  23:         });
  24:     });
  25:  
  26:     app.get('/set', function (req, res) {
  27:         var key = req.param('key');
  28:         var value = req.param('value');
  29:         client.set(key, value, function (error, reply) {
  30:             if (error) {
  31:                 res.send(500, error);
  32:             }
  33:             else {
  34:                 res.send(200, reply);
  35:             }
  36:         });
  37:     });
  38:  
  39:     app.get('/ping', function (req, res) {
  40:         res.send(200, 'PONG!');
  41:     });
  42:  
  43:     var server = app.listen(process.env.port || 3000, function () {
  44:         console.log('Listening on port %d', server.address().port);
  45:     });
  46: })();

Then I deployed it to Azure Web Site belongs to another Azure Subscription and as you can see I can retrieve the item successfully.

11

I can set new item into Redis from this web service.

12

And retrieve it from the web application in Cloud Service in another subscription.

14

And I can retrieve it from the Web Site as well.

15

 

Use Pub Sub Mode

Redis can be used as a distributed key-value cache, as what I demonstrated above. And it supports list and hash as well that we can save entities in a list or hash and retrieve them together. Besides, Redis support pub/sub mode that can be used as a message queue. Now let's try to change my application to use the pub/sub mode.

Firstly I need to modify the Web Site ASP.NET application so that user can publish message. I used the "About" page to do it. The layout will be changed as below that I can specify the channel name and message and publish to Redis.

   1: <%@ Page Title="About" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="ShaunAzureRedisDemo1.About" %>
   2:  
   3: <asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
   4:     <h2><%
   1: : Title 
%>.</h2>
   5:     <h3>Publish</h3>
   6:     <p>
   7:         Channel: <asp:TextBox ID="txtChannel" runat="server" Text="shaun_channel"></asp:TextBox>
   8:     </p>
   9:     <p>
  10:         Message: <asp:TextBox ID="txtMessage" runat="server" Text=""></asp:TextBox>
  11:     </p>
  12:     <p>
  13:         <asp:Button ID="btnPublish" runat="server" Text="Publsih" OnClick="btnPublish_Click" />
  14:     </p>
  15:     <p>
  16:         <asp:TextBox ID="txtTrace" runat="server" ReadOnly="true" TextMode="MultiLine" Height="200" Width="100%"></asp:TextBox>
  17:     </p>
  18: </asp:Content>

The backend code was like below.

   1: using ServiceStack.Redis;
   2: using System;
   3: using System.Collections.Generic;
   4: using System.Linq;
   5: using System.Web;
   6: using System.Web.UI;
   7: using System.Web.UI.WebControls;
   8:  
   9: namespace ShaunAzureRedisDemo1
  10: {
  11:     public partial class About : Page
  12:     {
  13:         private static RedisClient _client = new RedisClient(
  14:             "shaunrediscache.redis.cache.windows.net", 
  15:             6379, 
  16:             "Kl7UaxeZiqA1QbclSsI02mDndOccxwD6AluliF1axmA=");
  17:  
  18:         protected void Page_Load(object sender, EventArgs e)
  19:         {
  20:         }
  21:  
  22:         protected void btnPublish_Click(object sender, EventArgs e)
  23:         {
  24:             var channel = txtChannel.Text;
  25:             var message = txtMessage.Text;
  26:             try
  27:             {
  28:                 var id = _client.PublishMessage(channel, message);
  29:                 txtTrace.Text = string.Format("Sent! ({0})", id);
  30:             }
  31:             catch(Exception ex)
  32:             {
  33:                 txtTrace.Text = ex.ToString();
  34:             }
  35:         }
  36:     }
  37: }

Next I will create another Node.js application and deployed to Azure, which will subscribe the channel and print the message content when anything came. Below is the new Node.js file "app.js".

   1: (function () {
   2:     'use strict';
   3:  
   4:     var redis = require('redis');
   5:  
   6:     var client = redis.createClient(6379, 'shaunrediscache.redis.cache.windows.net');
   7:     client.auth('Kl7UaxeZiqA1QbclSsI02mDndOccxwD6AluliF1axmA=');
   8:  
   9:     client.on('subscribe', function (channel, count) {
  10:         console.log('subscribed to channel "' + channel + '"');
  11:     });
  12:  
  13:     client.on('message', function (channel, message) {
  14:         console.log('[' + channel + ']: ' + message);
  15:     });
  16:  
  17:     client.on('ready', function () {
  18:         client.incr('did something');
  19:  
  20:         client.subscribe("shaun_channel");
  21:     });
  22: })();

Once I deployed both of them I can open the Kudu Console of the Node.js Web Site and start the "app.js" from the console page.

The Kudu Console is an administration for each Azure Web Site application.

If your website address is http://shaun.azurewebsites.net/ then the Kudu Console address would be https://shaun.scm.azurewebsites.net/

Then I published a message from the web site as below.

16

Back to the Kudu console as you can see the Node.js application received the message from my Redis.

17

And I can send more messages and the Node.js keep receiving them and print out.

18

 

Summary

In this post I demonstrated how to create the new Azure Redis Cache, how to use it from C# and Node.js, and how to use it as a message queue.

Redis is very powerful and popular in open source community. People uses in vary ways such as  distributed cache, NoSQL database and message queue. Previously we can install Redis server in our virtual machine, or use the virtual machine image which pre-configured with Redis installed. But both of them we need to deal with the configuration and maintenance. Now we can use Redis by creating a new Redis Cache Service and scale-up and down as we want, without any effort in installation, configuration, etc..

 

Sample code.

 

Hope this helps,

Shaun

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.

Comments

Gravatar # re: Redis Cache (Preview) in Microsoft Azure
Posted by rick anderson on 5/29/2014 8:32 AM
Yes the password is the real one. Please be nice, thank you.
Please don't show passwords, it sends the wrong message.
Gravatar # re: Redis Cache (Preview) in Microsoft Azure
Posted by Shaun Xu on 5/29/2014 9:51 AM
@rick, thanks for your kindly reminder. It's just a joke I had removed the redis service in the demo so the password is expired. :P
Post A Comment
Title:
Name:
Email:
Comment:
Verification: