Friday, September 23, 2011

Does Redis Undermine a Key REST Tenet?

While I have always admired the elegance of REST's resource model and its standardised verbs and status codes, there are two things about the RESTful style that I think are drawbacks when building complex applications. One is its client/server model rather than a peer-to-peer model, which I think would have been more generic and useful, especially when unsolicited notifications need to be supported. The second, which is what I want to talk about now, is the insistence on statelessness (or alternatively forcing anything stateful to be either managed by the client or modelled as a resource). This is an acceptable approach for application domain-specific elements, but there is also a domain-neutral class of session-stateful elements that are useful for providing Qualities of Service (such as a sliding window of message sequence numbers for reliability, or session keys for security). These are common requirements that any application may require. This kind of session state is fundamentally different from domain-specific state, e.g., a shopping cart in an e-commerce application which would not be relevant to any other type of application.

The lack of support for this application domain-neutral subset of session state within the RESTful style of design costs us the ability to provide Qualities of Service in a uniform way (which the much-disdained WS-* is able to do using standards like WS-SecureConversation/WS-Security and WS-ReliableMessaging). [Many will point out that RESTful applications can use SSL for security, but the SSL protocol is not itself RESTful, and it breaks the cacheability and routability of REST operations.] So Qualities of Service end up becoming an application responsibility in RESTful applications, which has always struck me as a bit of a cop-out on the part of the protocol.

REST has standardised many other aspects of interaction and turned them into a uniform protocol that interacting systems can use. I would like to see QoS-related session management also similarly standardised and "pulled into the protocol", even if that protocol is not HTTP but something else (WebSockets?).

I have often wondered exactly why statefulness is considered "evil". There are two reasons, as far as I can tell - scalability and failure recovery. Session state occupies memory, so holding session state for multiple clients impacts the scalability of a server. Also, holding session state within a server makes it less easy for clients to switch to another if the one holding its session objects goes down. We'll need to have session-aware clusters rather than stateless farms of servers to provide failover, which again doesn't scale linearly.

Two considerations make these arguments weaker.

The first is that we are not talking about application-specific session state like shopping carts and the like. We're talking about relatively tiny data elements that are domain-neutral and dedicated to providing Qualities of Service, such as sliding windows of sequence numbers for reliability, and security tokens for message encryption. These aren't huge, perhaps a few hundred bytes at most.

The second is that the advent of NoSQL databases has given us a way to delegate the storage of session state. It's now becoming recommended best practice to store session state in a NoSQL database like Redis rather than in memory. Delegating session storage is an alternative to session-aware clusters, since the servers can now be a simpler stateless farm and access the NoSQL database for shared session state. What's impressive about Redis in particular is that the complexity of its GET and SET operations is claimed to be of Order(1), i.e., constant time. This means that (in theory at least) one can increase the number of servers using a Redis datastore indefinitely with no impact on performance.

Now, a horizontally scalable farm of servers can share a Redis datastore and use it to hold the individual sliding windows of message sequence numbers for a number of clients, and also their security tokens. Scalability is no longer a problem, because the data elements are small and the storage/retrieval operations are of constant-time complexity. Failover is also not a problem since the servers themselves are stateless and switchable at run-time.

It would be good if a standard and application domain-agnostic mechanism could be evolved to provide security and reliability to REST-based interactions, using Redis-style scalable session storage. This may be the long-awaited successor to REST, which Rohit Khare's ARRESTED style attempted to do (but which has no practical implementation to date).

That will then leave client/server as my only bugbear with the RESTful style. We'll need another extension to handle that.

4 comments:

Mike Amundsen said...

Ganesh:

a few things come to mind in reading your post...

first, i'd like to hear more about your notion of " a domain-neutral class of session-stateful elements." do you mean cross-domain state? or do you mean generic static which can be applied to any domain-specific case? or possibly something entirely different that i've just missed? to date, i've not been able to imagine domain-neutral state (as i am thinking state occurs within an app domain context), so please feel free to help me sort that out.

second, "REST's refusal to support these in the the protocol..." seems like quite an odd turn of phrase. do you mean to say we'd have session has a protocol-level aspect of HTTP today (something we do not right now) except for Fielding's refusal to support such a thing? certainly you do not mean that REST is a protocol. i look forward to clarification.

third, "qualities of service end up becoming an application responsibility in REST" also strikes me strange. QoS is not at all part of Fielding's model (that i am aware of). possibly you mean that HTTP's lack of support for QoS means people who want QoS but insist on using a protocol void of this feature end up building it themselves over and over. but maybe that's not what you mean. please advise.

fourth, "statelessness is so evil" is just a lazy phrase, right? like "guns are evil" or "short people are unhappy" or something. your characterization of a constraint is "being" something is silly. i suspect you mean to say you do not agree w/ Fielding's selection of this particular constraint on order to support his list of "Architectural Properties of Key Interest." that would be a reasonable statement. i find your summary of the _reasons_ Fielding selected statelessness to fall short of his description, too. in fact, his dissertation does not include stateless in the scalability section at all, but in the evolvability section. i see nothing in your remarks that addresses this case.

fifth, it seems you are advocating for supporting stateful interactions for two reasons: 1) the data is small, and 2) we have a technology which allows for "delegation" of this task. again, neither of these elements seem to address Fielding's reasons for advocating scalability.

finally, i should say that i am encouraged that you are considering the possibilities that Fielding's decade-old style might be replaced w/ one more in tune with the tools and technologies available today. certainly much has changed since Fielding created his matrix of architectural styles" upon which he based his selection of constraints which would provide his desired system properties. i would be interested to see your list of desired properties and the constraints you select to encourage them.

as a final aside, Fielding's work is no science; not a theory to explain what we see that will be eventually proved "false" (i.e. "all planet orbit in perfect circles", etc.). instead Fielding's work is engineering; a style, a methodology. while it is possible new technologies, techniques, etc. could evenutally render Fielding's approach "passe" (we use plastics for many things that, in the past were done w/ other materials), these advances will not "weaken" or "undermine" his methods (clay pots still hold water just like they did before plastic was invented).

Mike Amundsen

Ganesh Prasad said...

At last, a comment! Someone has read this :-).

Thanks, Mike. Let me try and answer your questions.

1. I mean generic state that can be applied to any application domain. Think session keys for security or sliding windows for reliability.

2. You're right about the confused phraseology. It's HTTP that is stateless, of course. However, REST's only practical implementation is HTTP, and REST essentially approves of the statelessness choice as part of its architectural style.

3. I should have said "QoS ends up being an application responsibility in RESTful applications". Thanks for pointing out that bit of sloppiness.

4. The "statefulness is evil" phrase is not necessarily from Fielding. It's one of the accepted truisms in software engineering.

5. No, I'm not *advocating* statefulness because of these two reasons (data being small and the possibility of delegation). The reason for allowing a degree of statefulness is to enable QoS. These two reasons are to show that the traditional reasons to disallow statefulness have been mitigated.

I'm working on what it might look like to apply resource-orientation to peer-to-peer systems with support for domain-neutral state. Stay tuned.

And sure, I don't see REST as a theory to be disproved. It's elegant and useful and I've been an advocate for it wherever I have worked. I think there may be an opportunity to extend it to address two specific areas (peer-to-peer and QoS), that's all.

Regards,
Ganesh

Integral ):( Reporting said...

>> One is its client/server model
>> rather than a peer-to-peer model,

Ganesh, I am so surprised of this comment. Why didn't I think of that before?

JJ-

Mike Amundsen said...

Ganesh:

thanks for the follow up comments; they are much appreciated.

any chance we can continue our discussion via email (mamund -AT- yahoo -DOT- com)?

Cheers!