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/
