You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Amit Chandel <am...@gmail.com> on 2009/03/01 03:02:14 UTC

serializing session in DB

Hi Group,

I am trying to deploy a tomcat cluster. I was able to set up a test
tomcat cluster using in-memory replication with version 6.0.10, but my
session data is too much (almost 5 GB per tomcat instance, and using 2
nodes in cluster both instances will require 10GB of RAM to hold
session data). So I fall back on storing session in database for which
I used Persistent Manager and JDBCStore. But the problem is that its
not full proof HA. The sessions are only persisted when they become
idle or during graceful shutdown of the tomcat. Is there a way to
persist the session in DB before the request gets served (as it
happens for in-memory replication).

Thanks,
Amit

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: serializing session in DB

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Amit,

On 3/2/2009 9:58 PM, Amit Chandel wrote:
> I would love to see an example of such a filter.

All you need to do is wrap the HttpSession object with one that does
your database access. Something like the filter below. There are a few
things missing:

1. The implementation of the readStoredKeys, readStoredValue,
writeStoredValue, removeStoredValue, and expungeSession methods.

2. Error handling. Presumably all of this will be done in the above methods.

3. Caching of session data. The session effectively contains no data at
all; the database contains everything. (See below for a crucial problem
with this example filter).

4. Stub methods for the HttpSession wrapper class that call
_wrapped.foo() for each foo() method.

5. IMPORTANT NOTE: since this class assumes all the data is in the
database and nothing will be stored in memory, the methods setAttribute
and removeAttribute are never called on the wrapped HttpSession object.
This has the undesirable effect of /not notifying any of the
HttpSessionAttributeListeners or HttpSessionBindingListeners/. You can
easily synthesize the calling of HttpSessionBindingListener methods, but
not the HttpSessionAttributeListener methods (because the listeners are
managed by the container). If you want these attribute listeners to be
notified, you'll have to call _wrapped.setAttribute() (or whatever)
which means that the data goes into your session: in memory.

Enjoy,
- -chris

public class JDBCSessionFilter
    implements Filter
{
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
        throws ServletException, IOException
    {
        if(request instanceof HttpServletRequest)
            request = wrap((HttpServletRequest)request);

        chain.doFilter(request, response);
    }

    protected class JDBCRequestWrapper
        extends HttpServletRequestWrapper
    {
        JDBCRequestWrapper(HttpServletRequest request)
        {
            super(request);
        }

        // Override getSession methods to use our wrapper
        public HttpSession getSession(boolean create)
        {
            HttpSession session = super.getSession(create);

            if(null == session)
                return null;
            else
                return new JDBCSessionWrapper(session);
        }

        // Override this method, too, in case the underlying
        // implementation doesn't call getSession(boolean)
        public HttpSession getSession()
        {
            return this.getSession(true);
        }
    }

    protected class JDBCSessionWrapper
        implements HttpSession
    {
        private HttpSession _wrapped;

        JDBCSessionWrapper(HttpSession wrapped)
        {
            _wrapped = wrapped;
        }

        // Implementation here depends on how you want your
        // session to act. This implementation is a simple
        // write-through, non-caching one.
        public Enumeration getAttributeNames()
        {
            return this.readStoredKeys(getId());
        }

        public Object getAttribute(String key)
        {
            // No data is kept in the session itself

            return this.readStoredValue(getId(), key);
        }

        public void setAttribute(String key, Object value)
        {
            // No data is kept in the session itself
            if(null == value)
                removeAttribute(key);
            else
                this.writeStoredValue(getId(), key, value);
        }

        public void removeAttribute(String key)
        {
            this.removeStoredValue(getId(), key);
        }

        // Remember to override getValueNames, getValue,
        // setValue, and removeValue to refer to the
        // above methods.

        public void invalidate()
        {
            _wrapped.invalidate();

            this.expungeSession(getId());
        }

        // Implement the remaining methods to simply
        // pass-through to the "_wrapped" member.
    }
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmtUV0ACgkQ9CaO5/Lv0PCMCACdF4yb9RQEyZSd/fvzmMZzCdPU
WHsAnjtdcMswZclf/0Q/tvQBk0p1TeYJ
=0xzb
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: serializing session in DB

Posted by Amit Chandel <am...@gmail.com>.
Hi Chris,

I would love to see an example of such a filter.

Thanks,
Amit

On Mon, Mar 2, 2009 at 5:43 PM, Christopher Schultz
<ch...@christopherschultz.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Amit,
>
> On 3/2/2009 4:21 PM, Amit Chandel wrote:
>> But only issue is that Tomcat doesn't persist sessions to DB
>> synchronously as is the case with in-memory replication where session
>> data is first replicated and then the request gets served. So if
>> master fails, and the session data has not been persisted, subsequent
>> requests going to the other tomcat node will see old session data
>> from DB, and might frustrate the *user*. I would like to know how
>> synchronous persistance of session data with Tomcat is done in
>> practice.
>
> I have no experience with JDBCStore, but you could always implement your
> own SessionManager that does synchronous database updates.
>
> If you don't want to implement a SessionManager (which might be a bit
> heavy-handed and certainly Tomcat-specific), you could also write a
> filter that wraps the HttpSession with your own object that does
> synchronous DB reads and writes. This might also save you a LOT of RAM.
> If you use the database exclusively for session attribute data, your
> in-memory footprint for sessions could drop dramatically.
>
> If you'd like an example of such a filter, I could probably provide one.
>
> - -chris
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkmsYPgACgkQ9CaO5/Lv0PBsWACfccJ6T9ZvIlRRhk65kpJ4BZc1
> 1ZoAniNvoh/NGQ5N1VnkGw5yr55S4hgN
> =xPGx
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: serializing session in DB

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Amit,

On 3/2/2009 4:21 PM, Amit Chandel wrote:
> But only issue is that Tomcat doesn't persist sessions to DB
> synchronously as is the case with in-memory replication where session
> data is first replicated and then the request gets served. So if
> master fails, and the session data has not been persisted, subsequent
> requests going to the other tomcat node will see old session data
> from DB, and might frustrate the *user*. I would like to know how
> synchronous persistance of session data with Tomcat is done in
> practice.

I have no experience with JDBCStore, but you could always implement your
own SessionManager that does synchronous database updates.

If you don't want to implement a SessionManager (which might be a bit
heavy-handed and certainly Tomcat-specific), you could also write a
filter that wraps the HttpSession with your own object that does
synchronous DB reads and writes. This might also save you a LOT of RAM.
If you use the database exclusively for session attribute data, your
in-memory footprint for sessions could drop dramatically.

If you'd like an example of such a filter, I could probably provide one.

- -chris

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmsYPgACgkQ9CaO5/Lv0PBsWACfccJ6T9ZvIlRRhk65kpJ4BZc1
1ZoAniNvoh/NGQ5N1VnkGw5yr55S4hgN
=xPGx
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: serializing session in DB

Posted by Amit Chandel <am...@gmail.com>.
Hi Chris,

Thanks for bringing up these concerns.

I did a more detailed analysis of our application. Though it keeps 5GB
of session data in RAM which are actually disk backed, the active
session data will only account for a maximum of 200MB per second. So I
am only required to persist this much data in DB every second.

Going with the in-memory session replication will require 10GB of RAM
on both the tomcat instances. When the session data gets replicated to
another node, it gets written on disk of the other node too. Its a
Wicket application, and I can't just get away with replicating the
disk based session data :-(

If I go with persisting sessions in DB, my RAM requirement drops to
only 5GB on the cost of more network traffic and 200MB of DB writes
per second. We plan to use an NDB cluster for that. But only issue is
that Tomcat doesn't persist sessions to DB synchronously as is the
case with in-memory replication where session data is first replicated
and then the request gets served. So if master fails, and the session
data has not been persisted, subsequent requests going to the other
tomcat node will see old session data from DB, and might frustrate the
*user*.  I would like to know how synchronous persistance of session
data with Tomcat is done in practice.

Thanks,
Amit

On Mon, Mar 2, 2009 at 12:23 PM, Christopher Schultz
<ch...@christopherschultz.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Amit,
>
> On 2/28/2009 9:02 PM, Amit Chandel wrote:
>> I am trying to deploy a tomcat cluster. I was able to set up a test
>> tomcat cluster using in-memory replication with version 6.0.10, but my
>> session data is too much (almost 5 GB per tomcat instance, and using 2
>> nodes in cluster both instances will require 10GB of RAM to hold
>> session data).
>
> Wow, does this thing scale? 5 GB of session data is a /lot/. Have you
> considered using either db-backed sessions (that is, writing everything
> to the database instead of keeping it in memory) or having your
> application itself store things in the db instead of the session?
>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkmsFhYACgkQ9CaO5/Lv0PCK3wCdFKK3UW36VBjJuO/TgjmIQWoT
> YusAoJ1WNgnn7nnAul84qJ8E7MHHPlJB
> =G8Kk
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: serializing session in DB

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Amit,

On 2/28/2009 9:02 PM, Amit Chandel wrote:
> I am trying to deploy a tomcat cluster. I was able to set up a test
> tomcat cluster using in-memory replication with version 6.0.10, but my
> session data is too much (almost 5 GB per tomcat instance, and using 2
> nodes in cluster both instances will require 10GB of RAM to hold
> session data).

Wow, does this thing scale? 5 GB of session data is a /lot/. Have you
considered using either db-backed sessions (that is, writing everything
to the database instead of keeping it in memory) or having your
application itself store things in the db instead of the session?

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmsFhYACgkQ9CaO5/Lv0PCK3wCdFKK3UW36VBjJuO/TgjmIQWoT
YusAoJ1WNgnn7nnAul84qJ8E7MHHPlJB
=G8Kk
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org