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.
We use an old, custom caching mechanism here, which makes our server startup about 1-2 minutes, but improves overall performance afterwards many times over. We are constantly improving this mechanism and plan to replace it with hibernate caching once we get hibernate more integrated with our system. In my experience caching relatively static LOBs gives us the most benefit.
subject: App startup issue: Getting objects into an L2 cache.