A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.
I work on a small enterprise application which handles about 300 concurrent users. The server is all Java, uses Spring, Hibernate, Oracle and is accessed mostly through a rich client Java application but also via web services (for C++/Perl/Python integration). The server runs on a single Linux system.
We recently started using a Level 2 cache with Hibernate and things work great once certain objects have had their state cached. We have a couple of UI table views in our rich client which display a dense collection of information representing a large portion of our domain object model graph. Loading these UI views when the data they display is not in the cache is unacceptably slow, but once the data is cached it takes just a blink.
We've settled on a strategy with a cache loader which runs as soon as the application server is started. It does several simple HQL queries like "from SomeEntity where .." to get the important common data cached as part of startup. This cache loading takes a while, about 8-10 minutes.
The performance boost we've achieved by tuning our way to this strategy has impressed our users quite a bit, which is why we're sticking to it for now. Before Hibernate and the Level 2 cache came into the picture, these views were built from complicated SQL queries which were as tuned as we and our very talented DBA could get them. The new setup with the L2 cache is many times faster than these SQL queries, plus it feels more scalable since Oracle isn't being consulted as often.
Still, I can't help but feel like I took an application that started up quickly and had a small footprint and turned it into one that starts up slowly and uses lots of memory. It performs better, the tradeoff seems completely worth it, but I feel like a bad engineer each time I have to wait for the server to start. Cognitive dissonance.
Are any of you doing this sort of caching on startup? I've been looking around to get a sense of how common this practice is.
Thanks for listening,
Have you considered using materialized views? Instead of running
FROM a, b, c
to fill your cache, you
CREATE MATERIALIZED VIEW D
FROM a, b, c
and then run
SELECT * FROM d
or--depending on the complexity of the SQL, retain the original query and let the optimizer rewrite it. You can periodically refresh the materialized views as you think best.
> about 8-10 minutes
It's not much for enterprise, providing that app is accessible during that time. Restarts are usually done by support at deep night, so nobody is there to notice that 10 minutes of cache preloading. Our business banking app takes about 3 minutes to start -- no caching at all, just too many interdependent modules.
P.S. If I were you, I'd buy the Tangosol Coherence as a L2 cache for Hib. There are countless tuning settings in it.
P.P.S. Still, the amount of cached data is somewhat worry me. Cache is not completely transparent. It could behave differently from the actual DB, especially if write-back is used. Might be, you should look for ways to improve view performance, not cache it over-aggressively...
Saturday, February 18, 2006
>Are any of you doing this sort of caching on startup?
Our J2EE app loads and caches frequently used data upon startup and defers loading and caching of less frequently used data until such time it is explicitly requested, i.e. "lazy-loading".
This allows for a smaller memory footprint and shorter app startup times than if everything is cached upon startup. Correctly done, it also provides reasonable response times to users.
Thanks. We do use lazy loading copiously in our application. The special thing about our application seems to be the view users are presented with upon login, which is a table containing data from lots of our domain objects, several flattened one-to-many relationships and some columns derived from computations. I'm starting to realize that this table view is a unique challenge for this specific application and I'm getting comfortable with the design decisions I've made to get it to run so responsively, this is the most important consideration at this time. Software design is all about tradeoffs.
Thanks for the feedback.
This topic is archived. No further replies will be accepted.Other recent topics
Powered by FogBugz