What are user sessions and why we need to avoid them?
What are user Sessions in a Software Application? Do we need them? If not how to achieve sessions in Stateless application?
User Session is a temporary collection of objects stored in memory for a specific user with strict time to live (TTL)(eg. 30 mins). Remember JSESSIONID ?
- We have a cluster of application nodes — N1, N2 & N3 — all running server instances.
- User logs into the application
- They land in a server node — N1
- In N1, application pulls user’s metadata — for eg. preferences, configurations etc., and stores them in a user Session object — local session(preserved in memory or high performance cache/datastore with an expiry time)
- Hereafter, all future requests for this user is routed to same node N1 by the load balancer. This is known as sticky session. To achieve stickiness a special header or session based cookie (eg. JSESSIONID) will be used.
- Same user session object is fetched from cache/session store (without hitting backend data layer)
Now, in the above example, let us say node N1 goes down for some reason, we will lose all the sessions stored in N1. So by design we keep a replica of N1:sessions in say N3.
If node N1 goes down, requests are routed to N3 and N3 now serves both N1 & N3. N1 recovers & new requests will go there. N3 will continue to serve users with capacity equal to two nodes.
Then application servers like ATG Dynamo brought the concept of Session Federation — which balances the sessions across all nodes & load balance the traffic accordingly whenever there is change to number of active nodes. They flush sessions from node to node, keeping a registry of session to node mapping in a node. That will have a replica as well. See, now this is getting complicated.
Developers started using this utility object (session) conveniently for storing tons of other metadata about the user — to avoid expensive DB calls. Now, sessions started to grow like kitchen sink. Imagine if you have JVM with > 50% of memory used for storing sessions.
Session OR state management was a fancy design pattern of 2000s, it is not followed anymore. So we may see this in legacy applications. Newer applications follow a simpler approach.
- Session Repository
Instead of every node managing sessions, manage them in a central high speed cache datastore like Memcached or Redis.
- Now, nodes need not worry about maintaining local Sessions
- Application Load-balancer need not route the user requests to same node N1. In other words no sticky sessions.
- All we have to do is design the cache for resiliency — cluster with failover nodes
2. Completely Stateless or No concept of sessions
Remove the need for sessions altogether. For performance, better data modeling should help. If we are dealing with existing low performant infrastructure, use caching as needed.
One positive outlook is — the concept of sessions or sticky sessions could help us with Testing a feature going live. Imagine you are pushing code & you want to test the application with your request hitting the latest version of the application — ec2 instance / k8s pod. AWS Classic ELB supports sticky sessions and so does k8s (session affinity). However, this need not be used for managing user sessions.