EJB Cache

Discussions

Performance and scalability: EJB Cache

  1. EJB Cache (30 messages)

    Does anyone know how to create an EJB that serves as a cache for data. I would like to store data from the database in the app server to reduce the load on the database. I was thinking of developing an entity bean that is created and put into a transaction when the server starts. It would initiallly retrieve the cached data from the database. Clients would always use the same primary key to find the bean. Is this right or is there some other way?

    much thanks

    Threaded Messages (30)

  2. EJB Cache[ Go to top ]

    Eric,

      That is a very interesting proposition. You are suggesting modeling an Entity Bean essentially as a singleton (everyone calls it by the same PK) and using it to store a cache. I guess this could work if you can make your app. server never passivate your bean. This would be highly app. server specific.

       One alternative which I think is portable is to set a really high timeout period (is that a portable EJB deployment descriptor option?) on the bean, and load up the entire graph of data on ejbLoad(). The cache could last a long time if frequently accessed, or it would timeout after your specified timeout period.

        One popular method of creating a cache is to use a static singleton class, and populating it using static initializers. This class will last as long as the VM is running.

    Floyd
  3. EJB Cache[ Go to top ]

    Hi all,

    The problem described is something every EJB app designer faces; a cache in EJB's.

    I myself basically fixed it the same way: one entity that everyone calls by same the same primary key. It works, but it's very ugly.

    What about that last thing you said? Static singleton class? Initialize it with static initializers?
    Could you be a little more specific? I, too, am very interested in a clean way for implementing a cache for EJB's.

    Erik
  4. EJB Cache[ Go to top ]

    Are there any threading issues when using Singletons?
  5. EJB Cache[ Go to top ]

    Justin,

    Of course. Since there's only one instance, your threads can access it simultaneously. So you'll have to make sure you synchronize data manipulation.

    Erik
  6. EJB Cache[ Go to top ]

    Hi all,

    I think implementing your own ejb bean cache is a moot point because most vendors do this automatically for you! Within a transaction, ejbLoad of a specific bean instance will get called only once; Outside a transaction, if you have data that changes infrequently, then assign that bean as a ReadOnly bean and set a long refresh-timeout (Weblogic allows you to do this; I'm sure other vendors have similar implementations.)

    Implementing your own singleton bean cache is dangerous under a clustered environment; Weblogic's implementation guarantees a single bean instance per primary key PER SERVER INSTANCE, but this does not preclude multiple instances of the same bean across the cluster! How do you propose to synchronize these bean instances, or a singleton cache across a cluster? Sure you can use JMS, which is 1) messy to implement and 2) because of its asynchronous messaging nature, it cannot guarantee you clean data.

    I guess my message is to study up on the bean cache implementation of your specific vendor! Chances are they've done all the homework for you already.

    Gene Chuang
    Teach the world... Join Kiko!
  7. EJB Cache[ Go to top ]

    Implementing your own caching is not a moot point if the functionality you have in mind is different from caching strategies offered by EJB container.

    Using singletons in a clustered enviroment is a bad idea, so RMI should be used instead.
  8. EJB Cache[ Go to top ]

    Gene,

    I agree with Dimitri about avoiding vendor specific cache strategies. I use Weblogic myself and of course have tried the read-only strategy.
    Nevertheless, I don't sleep well, knowing I created an EJB system that undermines the very idea of EJB: standardized software modules that can be deployed in any application server.

    However, Dimitri suggests using RMI. My guess is that he means an external cache application over traditional RMI (non-EJB), so EJB's in separate JVM's all talk to this synchronized cache application.

    Obviously this is not ideal. Not only does this RMI-based cache form a vulnerable single point of failure, it can also become a serious weak spot when it comes to performance.

    That's why I like a more distributed solution: a cache in every JVM, implemented as a singleton.

    Keeping singleton cache implementations in a clustered environment synchronized isn't that hard to realize. You already mentioned JMS yourself.
    Most important is that all cache instances contain exactly the same set of data. When they're being updated they should at all times stay equal (transactions that run over multiple app servers might otherwise suffer severe inconsistencies).
    This can very well be accomplished using JMS and some logic to lock the cache during update.

    Erik
  9. EJB Cache[ Go to top ]

    I suggested using RMI to implement singleton pattern in general -

    'cluster' singleton will be pinned RMI object which is singleton in the cluster and all JVMs in the cluster will be accessing it,

    'local' singleton will be registered locally, and, if server is smart enough, there will be no RMI overhead using the local object.

    That way you can access these singletons from EJBs without violating EJB programming restrictions and have control over singletons behaviour in a cluster.

    If these caches are distributed, synchronization can be done using SessionSynchronization interface, if all updates are facaded by a session bean - it can lock caches (if that's desired behaviour) before transaction begins and unlock/update them after transaction commits.

  10. EJB Cache[ Go to top ]

    Hi,

    But what about a singleton cache undermining the main purpose of clustering: failsafety? What if the VM containing the singleton in a cluster crashes?

    Gene
  11. EJB Cache[ Go to top ]

    Using RMI to implement caches developer has full control of how it is going to be used/deployed:

    - 'cluster' singleton - RMI object pinned to a specific server in a cluster. Only one instance exists in a cluster.

    - 'local' singleton - RMI objects running locally on every server in a cluster(also this avoids RMI overhead if server is smart enough). Multiple instances exist in a cluster, but they are singletons from the point of view of a local JVM.

    - 'cluster-aware' - when this RMI object is cluster-aware (for example, using Weblogic, it is compiled with -clusterable ... rmic options).

    When multiple cache instances are present in a cluster some mechanism should be used to keep them all in sync. I used to publish JMS messages from afterCompletition(boolean commited) method - assuming that session bean is used to orchestrate updates which can invalidate cached objects and it worked just fine.
  12. EJB Cache[ Go to top ]

    I agree about RMI objects introducing a single point of failure. Singletons tend to be crucial objects in an app, so a failure could be disastrous. What about keeping the singleton cache in the web tier (assuming servlets are accessing the EJBs)? This has the added advantage of minimizing remote calls. The cache would then cache Serializable "details" objects, not bean references, ensuring disconnection from the server.
  13. EJB Cache[ Go to top ]

    Rod,

    Sure, a cache on the webtier is useful. Just as useful as a cache on _every_ tier.

    No matter how you look at it, in a multitier architecture, you're always looking for ways to minimize calls to the tier below you. Especially since the multitier architectures often also looks like a tree, where the most upper tier (i.e. webtier) tends to be larger (more servers) than the middletier and dbms tier.

    Basically caching systems make sense everywhere, including on EJB level.
    Just like a computer system has multiple levels of processing, it also has multiple levels of caching: level1, level2 and often level3 cache.

    Erik
  14. EJB Cache[ Go to top ]

    Why not using the singleton to store the data and then bind the object in the JNDI space of the application server to provide acccess to the same data to all servers in the cluster?! I already did that, not from within EJBs, but from outside, and you can store objects in a JNDI data store using a unique key (LDAP for example) !

    If the server that holds the singleton crashes then ... well, you're in trouble, unless you build you own recovery mechanism ( Gemstone/J has its own Persistent Data Store that does all that automatically) ... I assume that on each server in the cluster in the JDNI space will be stored a remote reference to the real singleton, therefore when the reference becomes invalid an exception will be thrown and you can rebuild the singleton.

    Eugen
  15. EJB Cache[ Go to top ]

    Eugen,

    In my message about caches on every level, I meant caches in general. I wasn't talking about having instances of the same cache in each level.

    Erik
  16. EJB Cache[ Go to top ]

    What about use a stateless session bean that grabs the cached data in it's setSessionContext() method. Granted, you might then get more than one instance of the cache, but presumably only if more than one was needed, in which case that would probably be a good thing.
  17. EJB Cache[ Go to top ]

    Can you talk a little bit in detail how to bind such a cache to a JNDI name which can be accessed remotely?
    What should be a "remote reference" for the "real" singleton?
    Can you put some fragment of code sample here?
    Thanks.
  18. EJB Cache[ Go to top ]

    Thanks for the responses and the idea about using a static singleton. That does seem like a better way than trying to keep a transaction open on an ejb. Since I want an object that can be found remotely, I guess I'll implement the object as an ejb but with static variables that are statically initialized.

    thanks
    eric
  19. EJB Cache[ Go to top ]

    Eric,

    Help me out here. Could you tell me a little more about this 'singleton' class stuff?
    It sounds like a clean solution, so I'm very interested, but I have no clue.

    Erik
  20. EJB Cache - with a Singleton[ Go to top ]

    Eric, you can't have static member variables in an EJB, its not allowed. Now that doesn't mean that an EJB cannot call some other static class.

      Erik, let me specify what I mean by a static singleton. Basically, its just a regular java class that uses a Singleton pattern (see the Gang of Four book called Design Patterns). The first time the class is called, it has not yet been initialized. At this point, the class will initialize itself, either by calling the database directly and loading itself up with data, or calling other EJB's and getting the data from them. Now, this plain java class contains data in it and can continually serve up this data for as long as the VM is running.

      Let me know if you need more clarification.

      Now Eric, my question is why not use your app. servers ability to cache your entity beans, since you know that this data is read only? This is what I do here on TheServerSide and it is damn fast. :)

    Floyd
  21. EJB Cache - with a Singleton[ Go to top ]

    Eric
    How does the app server cache your entity bean. I know of one method only ie isModified but that prevents only ejbLoad. How would one stop ejbstore to be called or to say delay calling ejbStore, Passivate...

    Mayank
  22. EJB Cache - with a Singleton[ Go to top ]

    Actually Mayank,

     You have it backwards. isModified prevents ejbStore, not ejbLoad. The only way to prevent ejbLoad is to tell your app. server to cache your entity beans (not call ejbLoad for a specified period of time).

    Floyd
  23. EJB Cache - with a Singleton[ Go to top ]

    Thanks Floyd for correcting the mistake and answering the question.

    if I have a have Bean which is mostly read only then I may specify a very large read time out period to avoid calls to ejbLoad.

    What happens If there are 10 Entity Beans representing same data and one of them happens to change some value. Will the container take care of calling ejbLoad of all the instances or it will call ejbLoad after the specified read time out period specified.

    Mayank
  24. EJB Cache - with a Singleton[ Go to top ]

    It is impossible to have 10 entity beans representing the same data (having the same primary key). There can only be one entity bean per primary key in memory.

    Floyd
  25. EJB Cache - with a Singleton[ Go to top ]

    Floyd,
    Page 184 and 185 of Mastering EJB by Ed Roman.. mentions that Several entity beans Instances May represent the same underlying data .... and it is basically to boost up the performance ... Please lets discuss my previous question again after reading that para.

    Mayank
  26. EJB Cache - with a Singleton[ Go to top ]

    Floyd,

    You talk about the Gang of Four book called Design Patterns. I don't have the book, so I checked amazon. Is it "Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Grady Booch" from Addison-Wesley?

    Now back to the singleton pattern.
    Now I'm sure this is what this singleton-pattern is all about, but how can there be just one instance of this class? And how can an EJB get a reference to it?

    Erik
  27. EJB Cache - with a Singleton[ Go to top ]

    All,

    One other note about the use of a singleton within an EJB:
    As I understand it, the main reason that static data (singleton's included) are restricted is because of the location transparency of EJBs. Specifically, even though static data may have been initialized within a singleton in one EJB on one particular VM, that does not mean that the equivalent Singleton on a second VM in the same cluster is initialized, or that it is initialized with the same data.
    So long as you take this into consideration when designing/deploying your app, you should not have any problems with using Singletons or similar static data within your application.

    Philip
  28. EJB Cache - with a Singleton[ Go to top ]

    You can provide singleton functionality by registering RMI objects. That way you can implement singleton in a cluster (pinned RMI object), or register objects locally (also avoiding RMI overhead if the app server is smart enough), or make this service clusterable itself.
  29. EJB Cache - with a Singleton[ Go to top ]

    Floyd,

    Nevermind the singleton pattern. I found an excellent article about it online: http://members.tripod.com/rwald/java/articles/Singleton_in_Java.html

    I am still curious about the book you mentioned however. Amazon can't find anything with "Gang of Four".

    Erik
  30. EJB Cache - with a Singleton[ Go to top ]

    The Gang of Four refers to the 4 guys from Talegent that developed this work. It is the seminal work of patterns. The full title is
    "Design Patterns : Elements of Reusable Object-Oriented Software:"

    You can find it at Fat Brain

    http://www1.fatbrain.com/asp/bookinfo/bookinfo.asp?theisbn=0201633612



    Dan D
  31. EJB Cache - with a Singleton[ Go to top ]

    Eric, you can't have static member variables in an EJB,

    > its not allowed. Now that doesn't mean that an EJB cannot > call some other static class.

    All the methods in the remote interface and home interface
    can NOT be static or final. Also the actual implementation of the business methods in the bean class can NOT be static.
    The restriction of this comes from the requirements of RMI-IIOP.

    However, this absolutely DOES NOT imply that all the methods
    in the bean class implementation can NOT be static or final.
    Actually some private methods in the bean class and some data CAN be static or final. The programmer still has much flexibility in implementing EJB classes.