Friday, September 6, 2013

Access Windows Azure Cache Service from Node.js and Express

The Windows Azure Cache Service is a great mechanism for scaling out web applications deployed to Windows Azure Web Sites. It allows you to externalize and very quickly access session state from any instance of your web application.

With the azurecache module you can now access Windows Azure Cache Service from Node.js applications. The azurecache module allows you to connect to the cache service directly, but it also provides an implementation of a session store that can be used in any session-enabled Express application.

The azurecache module uses Edge.js to call into the .NET Windows Azure Cache Service client that ships as a NuGet package. As such the module only works on Windows.

Using Windows Azure Cache Service to store Express session state

First create your Windows Azure Cache Service instance following instructions at Scott Guthrie's blog. You will end up with an endpoint URL of your cache service (e.g. tjanczuk.cache.windows.net) and an access key (a long Base64 encoded string).

Then install the azurecache and express modules:

npm install azurecache
npm install express

Next author your Express application that uses the azurecache module to store Express session state in the Windows Azure Cache Service:

var express = require('express')
, AzureCacheStore = require('azurecache')(express);

var app = express();

app.use(express.cookieParser());
app.use(express.session({ store: new AzureCacheStore(), secret: 'abc!123' }));

app.get('/inc', function (req, res) {
req.session.counter = (req.session.counter + 1) || 1;
res.send(200, 'Increased sum: ' + req.session.counter);
});

app.get('/get', function (req, res) {
res.send(200, 'Current sum: ' + req.session.counter);
});

app.listen(process.env.PORT || 3000);

Lastly set some environment variables and start your server:

set AZURE_CACHE_IDENTIFIER={your_azure_cache_endpoint_url}
set AZURE_CACHE_TOKEN={your_azure_cache_access_key}
node server.js

Every time you visit http://localhost:3000/inc in the browser you will receive an ever increasing counter value. When you visit http://localhost:3000/get you will receive the current counter value. The value of the counter is stored as part of the Express session state in the Windows Azure Cache Service with a default TTL of one day. You can now scale out the application to several instances since the session state is externalized to the Windows Azure Cache Service.

Deploying Node.js apps using Azure Cache Service to Azure Web Sites

If you are not familiar with deploying Node.js application to Windows Azure Web Sites, this walkthrough will explain the process.

Deploying an Express application that uses the azurecache module to store session state requires that module dependencies are declared in the package.json file:

{
"name": "azurecachetest",
"version": "0.1.0",
"dependencies": {
"express": "3.3.8",
"azurecache": "0.1.0"
}
}

Once you deploy a Node.js application consisting of the package.json and server.js above to Windows Azure Web Sites, you still need to provide the credentials to Windows Azure Cache Service to it. Just as you were doing this using environment variables before, you can now set the application settings of your web site using the Windows Azure management portal:

image

You can also use the management portal to scale out your Express application to multiple instances, now that the session state is externalized to Windows Azure Cache Service:

image

After saving the changes, you can navigate to your site and see the azurecache module in action:

image

How fast is the cache?

What is the latency of accessing Windows Azure Cache Service from a Node.js application using the azurecache module? To find out, let’s deploy a simple latency test to Azure Web Sites. The HTTP server will execute 1000 sequential puts against the cache and return the average latency in milliseconds as an HTTP response:

var http = require('http')
, cache = require('azurecache').create();

http.createServer(function (req, res) {
var start = Date.now();
var count = 1000;
function one() {
cache.put('puttest', { first: 'Tomasz', last: 'Janczuk' }, function (error) {
if (error) throw error;
if (--count === 0) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('' + ((Date.now() - start) / 1000));
}
else {
one();
}
})
}
one();
}).listen(process.env.PORT || 3000);

Save, deploy to Azure Web Sites, and send a request:

image

The average latency of inserting into the cache is just a notch over 1 millisecond. Converting the test to measure the latency of getting data from the cache is trivial. Here is the result:

image

Similarly to put, a get is around 1 millisecond.

Note that you can only achieve such low latency for Node.js applications deployed to Windows Azure, since locality of data is a major factor in caching. If you run the same performance test by hosting the Node.js server on your developer machine, your latencies will be much higher (in my case they were around 50ms) since every call to the Windows Azure Cache Service needs to go from your developer machine to a Windows Azure data center.

So, go forth and scale out!

3 comments:

  1. Brilliant, thank you for this article! Looking forward to testing our the cache today. It's just what I was looking for :)

    ReplyDelete
  2. Hi Thanks for the article. I have encountered an issue where am unable to access the cache service.

    The error says - "There is a temporary failure. Please retry later. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. For on-premises cache clusters, also verify the following conditions. Ensure that security permission has been granted for this client account, and check that the AppFabric Caching Service is allowed through the firewall on all cache hosts. Also the MaxBufferSize on the server must be greater than or equal to the serialized object size sent from the client.). Additional Information : The client was trying to communicate with the server"

    This error doesnt happen in my .NET code where am also accessing the cache service but only throws up when i access the cache service from my node.js code. After looking on web i got to know that this might happen if there is a mismatch between versions of azure sdk and azure caching. But am using the latest versions of all SDKs. Am using Azure SDK fro .NET 2.1, Azure caching 2.1 and the latest azure node.js sdk released on 22-08-2013. Can you please let me know how i can resolve this issue. I have been banging my head about it from the past few days.

    Thanks

    ReplyDelete
  3. http://stackoverflow.com/questions/19498120/unable-to-connect-to-azure-cache-service-from-node-js

    ReplyDelete

My Photo
My name is Tomasz Janczuk. I am currently working on my own venture - Mobile Chapters (http://mobilechapters.com). Formerly at Microsoft (12 years), focusing on node.js, JavaScript, Windows Azure, and .NET Framework.