JBoss Cache as a POJO Cacheby Ben Wang
In-memory caching is a crucial feature in today's large-scale enterprise applications, where scalability and high performance are required. An in-memory cache can store either application state information (e.g., a
HttpSession in a web application) or database query results (i.e., entity data). Since many enterprise applications run in clustered environments, the cache needs to be replicated across the cluster. Furthermore, if greater reliability is needed, the in-memory cache should also be persisted to the hard disk or database.
Most existing in-memory caching solutions fall into the category of what we call a "plain" cache system, in which the direct object references are stored and cached. Since a plain cache deals with the object references directly, it acts like an elaborate
HashMap and thus is very intuitive to use. When an object needs to be replicated or persisted in a plain cache system, the object has to implement the
Serializable interface. However, a plain cache also has some known limitations relating to replication or persistency:
- The user will have to manage the cache specifically. For instance, when an object is updated, a user will need to execute a corresponding API to update the cache content.
- The need for Java object serialization could hamper performance. If the object size is huge, even a single field update would trigger serialization of the whole object and replication across the cluster. Thus, it can be unnecessarily expensive.
- Java object serialization cannot preserve the relationship between cached objects. In particular, the cached object cannot be referenced multiple times by other objects (multiple referenced), or have an indirect reference to itself (cyclic). Otherwise, the relationship will be broken upon serialization. For example, Figure 1 illustrates this problem during replication. If we have two
Personinstances that share the same
Addressobject, upon replication, it will be split into two separate
Addressinstances (instead of one).
Figure 1. Plain cache does not preserve object relationship during serialization
Addressing the above problems in plain cache system, there is another new category of cache system: the POJO (plain old Java object) cache. A POJO cache is a system that acts as an "object-oriented" and distributed cache. In this system, once a user attaches the POJO to the cache, the caching aspect (e.g., replication and persistence) should be transparent to the user. A user would simply operate on the POJO without worrying about updating the cache content or maintaining the object relationship. There is no explicit API called to manage the cache. In addition, it has three more characteristics:
- There is no need to implement the
Serializableinterface for POJOs.
- Replication (or even persistence) is done on a per-field basis (as opposed to the whole object binary level in plain cache), resulting in a potential boost to performance.
- The object relationship and identity are preserved automatically in a distributed replicated environment. This enables transparent usage experience and increases software performance.
A leading in-memory POJO cache solution is the open source JBoss Cache. JBoss Cache is the first Java library that supports replicated, persistent, transactional, and fine-grained caching. It can be used both as a POJO cache and a plain cache. Since the JBoss Cache is 100 percent Java-based, it runs in any Java SE environment, including inside of an application server or as a standalone process. JBoss Cache has been used inside of the JBoss application server for EJB 3.0 stateful session bean clustering and HPP session replication, for example.
In this article, we demonstrate how JBoss Cache can be used as a POJO cache (through its
JBossCacheAop component). A use case will also be given to illustrate key features in a distributed setting.