On Sun, Mar 14, 2010 at 1:10 AM, dormando <[email protected]> wrote:
>
> > That's right for the normal case. However, for the
> memcached-session-manager I just implemented a feature so that sessions are
> only sent to memcached for backup if session data was modified. To prevent
> > expiration of the session in memcached, a background thread is updating
> sessions in memcached that would expire ~20 seconds later in memcached (if
> there would be some kind of "touch" operation I'd just use
> > that one). When they are updated, they are set with an expiration of the
> remaining expiration time in tomcat. This would introduce the issue, that
> the update would push them to the head of the LRU, but
> > their expiration might be e.g. only 5 minutes. So they would be expired
> but won't be reached when the 50 items are checked for expiration.
>
> Are sessions modified on every hit? or just fetched on every hit?

Nope, basically it's like this: on every request (with an associated
session) the session is served from local memory (the jvm local session
map). When the request is finished, the session is sent to memcached (with
the session timeout as expiration, e.g. 3600). It's still held in the local
session map, memcached is just there as a kind of backup device. The session
is only pulled from memcached, if a tomcat originally serving this session
(say tomcat1) died and therefore another tomcat (tomcat2) is asked to serve
this session. tomcat2 then does not have a session for the requested
sessionId and therefore loads this session from memcached.

The case that I was describing before (sending only modified sessions to
memcached) is a feature for performance optimization: the asumption is, that
there are more requests just accessing the session but less requests that
actually modify the session. So the idea is that I don't have to update a
session in memcached that was accessed but not modified. The issue that had
to be handled then was only the case of the different timeouts/expiration
times:
- a session was first created/updated and stored in memcached: both in
tomcat and memcached it has an expiration of 1h
- this session is accessed 10 minutes later; as it was not modified it is
not updated in memcached. Then this session has an expiration of 1 hour
again in tomcat, but in memcached it's already 10 minutes old, so it would
expire 50 minutes later.

To prevent this premature expiration I used the mentioned background thread
to update the expiration of such items in memcached to the remaining
expiration time they have in tomcat. In the example above nearly 50 minutes
later the session would be updated with an expiration time of 10 minutes.



> I don't
> see how this would be different since active sessions are still getting
> put to the front of the LRU.

This would be true if the application would read them from memcached - which
is not the case here.


> When you modify a session isn't the
> expiration time of that session extended usually?

Yes, when accessed a session gets another hour on this earth (or what else
the session timeout is).


> Honestly, if you have a background thread that can already find sessions
> when they're about to expire, why not issue a DELETE to memcached when
> they do expire? Or even a GET after they expire :)
>
That's already done: sessions that are expiring in tomcat are deleted from
memcached

The issue that I described regarding sessions, that were only accessed by
the application but not modified and therefore were not updated in memached
was the following: when such a session (session A) is updated in memcached
(just before it would expire in memcached) with a new expiration time of say
then 10 minutes (the time that it has left in tomcat), it will be pushed to
the head of the LRU.
Another session (session B) might have been modified just 20 minutes before
and sent to memcached with an expiration of 60 minutes, this one will be
closer to the tail of the LRU than session A, even if session B will still
have 40 minutes to live - 30 minutes more than session A. And because it's
closer to the tail session B might be dropped before session A, even if
session A would already be expired.

However, this would only be an issue if there are too many sessions for the
available memory of a slab.

[...]

> > In my case this is not that much an issue (users won't get logged out),
> as sessions are served from local memory. Session are only in memcached for
> the purpose of session failover. So this restart could be
> > done when operations could be *sure* that no tomcat will die.
>
> Tomcat sounds like such a pisser :P Even with your backup thing I'd
> probably still add an option to allow it to journal to a database, and I
> say this knowing how to get every last ounce of efficiency out of
> memcached.
>
Tomcat provides a PersistentManager ([1]) which allows to store sessions in
the database. But this manager backups all sessions in batches every 10
seconds. For one thing scalability of the application is then directly
dependent from the database (more than it is already if a database is used)
and there's a timeframe where sessions can be lost. If the session backup
frequency is shortened, the database is hit more often. Additionally
sessions are stored in the database again and again even if they were not
changed at all. That was the reason why I decided not to use this.

Cheers,
Martin


[1]
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/session/PersistentManager.html


> -Dormando




-- 
Martin Grotzke
http://www.javakaffee.de/blog/

Reply via email to