[infinispan-dev] Fwd: Transaction Semantics when using CacheLoaders and CacheWriters
A very interesting thread in the JSR-107 group, which appears just as Mircea has looked into the XA transactions and cache loaders/stores. Going back to that thread, it wasn't very clear what would happen if Infinispan caches were configured with XA transactions and they had a cache store. What's should a user expect in that case? IOW, how does our approach here compare to what's being suggested in the thread below? My feeling is that we're doing a variant of Option 3, where each cache store will run its own transaction (if they support it...) @Manik, It's also interesting from a data grid perspective since it highlights the boundaries of a cache vs data grid in this area. Cheers, Begin forwarded message: From: Brian Oliver brian.oli...@oracle.com Subject: Re: Transaction Semantics when using CacheLoaders and CacheWriters Date: August 1, 2013 5:55:14 PM GMT+02:00 To: jsr...@googlegroups.com Reply-To: jsr...@googlegroups.com Thanks for your feedback. It's much appreciated. Interestingly Oracle Coherence mostly takes much the same approach. Transactional (XA) Multi-Version-Concurrency-Control Caches don't allow Cache Loaders or Cache Writers (or Expiry) aka: a stronger form of Option 2. Personally I don't really classify these Caches as Caches (as eviction and expiry isn't supported). In essence they are really a transactional map, but leverage the Coherence NamedCache interface. Ultimately it's pure Data Grid functionality. While I think developers may like to think Option 1 is possible, when anyone explains the cost of this, they reluctantly decide to use Option 2, or move to using Entry Processors - which provides the atomicity for the most part. Historically Coherence also supported a form of Option 3 - but that also presents some challenges. I'm trying hard to find an answer to these challenges, but the way forward is unclear. What I can tell from our discussions here, in this group and at conferences, those that have shown interest in transactionality of Caches aren't really wanting Caches. They want an fast in-memory data-stores, perhaps like a map or nosql, to transact against, because they don't want to transact against a database. Why? They are seen as bottleneck or they are seen as being to slow and are trying to solve the architectural problem of the layer below their application tier. They like to call these Caches, because they are in-memory, but technically they aren't Caches. When you get down to it, ultimately the features and semantics being requested aren't really caches. So perhaps this is where the Data Grid specification can come into play? With my standardization hat on, my biggest concern is that anytime a developer needs to change their application, say between vendors, especially to adopt transactions that are implementation specific, it leads me to believe there's something wrong with the specification. Personally I think we should be making it easier to adopt not harder. On Thursday, August 1, 2013 10:55:21 AM UTC-4, Brian Martin wrote: Brian, I think you are spot-on with the problem and this is why we don't currently (in WebSphere eXtreme Scale) allows Loaders to be part of a distributed transaction that cross containers [your option 2]. If the transaction is to a single container, then we allow the local transaction (a believe this is equivalent to a variation of your option 3).As your dialog indicates, the scenario is messy and I don't like the state we are in currently with different capabilities depending on how many containers are enlisted in your transaction. At the moment, I don't have a better suggestion but I think your concern is valid and we should hash at a solution the community agrees with. Brian Martin IBM WebSphere eXtreme Scale On Thu, Aug 1, 2013 at 9:55 AM, Brian Oliver brian@oracle.com wrote: Hi All, I'd like to propose the challenge of how we think vendors should deal with transactions in the context of Caches with CacheLoaders/Writers configured, especially in the context of a distributed Cache. While this is an implementation concern, it's very important to see how this may be implemented as it very much effects the API design. As part of reviewing the specification with the Java EE team, and in particular how multiple-servers will interact, we've found a few challenges. In the spirit of openness, I've added some commentary to the following issue: https://github.com/jsr107/jsr107spec/issues/153 Currently I feel that the way the API is defined, all CacheLoader and CacheWriter operations will need to be performed locally which fundamentally prevents efficient (or any) implementation in a highly concurrent and distributed manner. Furthermore, interaction across multiple application processes, Java SE or otherwise may be a problem, simply because the API doesn't provide
[infinispan-dev] Query regarding Infinispan Clustering Performance
Hi, I am doing some analysis and study to see how the performance of infinispan can be improved in distributed clustered mode. This study is based on some performance test I ran, with 3 nodes, where replication performance seems better than distribution. But, I think distribution performance can be tuned with some best practices. Is there a way to divide the write requests coming on one node, equally among the cluster, so that transactions/second can be improved? Thanks, Faseela ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
[infinispan-dev] Infinispan 6.0.0.Alpha2 is out!
Dear Infinispan community, We're proud to announce the second Alpha release of Infinispan 6.0.0, and also the second release using the Apache Software Licence. New features in this release: - A new query DSL https://issues.jboss.org/browse/ISPN-3169 that is usable both in embedded/library mode and over HotRod. - Support for JCache 0.8 https://issues.jboss.org/browse/ISPN-3234, the Public Review Draft version of the JSR-107 specification. - A slimmer distribution, thanks to moving non-core cache store implementations to separate repositorieshttps://issues.jboss.org/browse/ISPN-3377 . For a complete list of features and fixes included in this release please refer to the release noteshttps://issues.jboss.org/secure/ReleaseNote.jspa?projectId=12310799version=12321854 . Visit our downloads http://www.jboss.org/infinispan/downloads section to find the latest release and if you have any questions please check our forums http://www.jboss.org/infinispan/forums, our mailing listshttps://lists.jboss.org/mailman/listinfo/infinispan-dev or ping us directly on IRC http://www.blogger.com/null. Thanks to everyone for their involvement and contribution! Cheers Dan ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
[infinispan-dev] Config of RemoteCacheStore(s) in HR RollingUpgrades
Hello guys, Tristan is on PTO and it would be very helpful for me if someone can comment here please: https://community.jboss.org/wiki/RollingUpgradesForRemoteClientsUsingHotRod#comment-12493 @Manik? Thank you in advance! Tomas ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] storeAsBinary keeps both the object and the byte[] - why?
Hi, Sorry for the delay getting back on this topic. Let me start with a little side node: I've been trying to find a previous discussion where I wondered about the merits/complexity/need of storeAsBinary. I'm pretty sure I made a point in the past about whether it was really useful but can't find the discussion. I do remember Manik replying back. Anyway, I'm not sure storeAsBinary really does reduce memory consumption and I'm not sure we have any measurements it shows it's quicker in certain scenarios. Even Martin, who investigated cache memory overhead, did not really use storeAsBinary to figure this out, and finally, we no longer need it for lazy deserialization since we have modular classloader in place. The only real use case I've found for it so far has been when developing the JSR-107 facade, and that's to provide store-by-value-like [1] capabilities (as opposed to our default behaivour which is store-by-ref), and even then storeAsBinary had to be tweaked. With this in mind, let me add my reply below… [1] https://github.com/infinispan/infinispan/blob/master/core/src/test/java/org/infinispan/marshall/DefensiveCopyTest.java On Jul 18, 2013, at 2:44 PM, Mircea Markus mmar...@redhat.com wrote: Hi, We have the following behaviour when storeAsBinary is enabled: - when an entry is added it is initially stored in binary format (byte[]) - when it is read from an *owning node*, it is unmarshalled and the object reference is cached in memory together with the byte representation - the object reference is only cleaned up when cache.compact() is invoked explicitly Assuming a key is read uniformly on all the nodes, after a while the system ends up with all the entries stored twice: the byte[] and the object in unserialized form. Of course this can be mitigated by asking the users to invoke Cache.compact - but that's quite confusing and not very user friendly as the user needs to be concerned with memory management. Can anybody think of some reasons why the value is kept twice? I mean besides optimising for local gets, which I think is not a good enough reason given the potentially huge memory consumption and the complexity added. From what I remember, this is to make local gets faster and avoid having to deserialize the entry all the time. However, this optimisation is useless for the only real use case for storeAsBinary that I mentioned above: store-by-value. That's cos whenever you send back an a value to the client, you don't send it as-is, but you send a copy back to avoid the user being able to modify the contents of the cache without calling a cache operation. This is easy to do just by deserializing the object stored in the cache whenever someone requests it. Clearly, if you're doing a lot of local gets it won't be very fast, but it's the price you currently have to pay to get safety. And when you want to store a value, you just serialize it and store it in the cache, making the original reference to the object useless to modify the cache contents. So, no, don't really see the reason to keep it twice. Cheers, Cheers, -- Mircea Markus Infinispan lead (www.infinispan.org) ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev -- Galder Zamarreño gal...@redhat.com twitter.com/galderz Project Lead, Escalante http://escalante.io Engineer, Infinispan http://infinispan.org ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] storeAsBinary keeps both the object and the byte[] - why?
On 18 Jul 2013, at 13:44, Mircea Markus mmar...@redhat.com wrote: Can anybody think of some reasons why the value is kept twice? I mean besides optimising for local gets, which I think is not a good enough reason given the potentially huge memory consumption and the complexity added. It is just to optimise for local GETs and GETs which hit L1. -- Manik Surtani ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
[infinispan-dev] storeAsBinary + lookup
Anything obvious on why this lookup doesn't find its match? Some background: * I have .ear, with 2 .war sub-deployments * each .war has own Key class in own gae.jar (in WEB-INF/lib) I do set storeAsBinary on the cache, which is shared between both .wars. This first key is the key for 2nd lookup. Below are entries of previous puts. As you can see, entry under [1] should match lookup key. But DataContainer returns null -- no match. -Ales --- key = {org.infinispan.marshall.MarshalledValue@11787}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=0}@8d2e9d9 instance = {com.google.appengine.api.datastore.Key@11063}Modules(1) parentKey = null kind = {java.lang.String@11855}Modules appId = {java.lang.String@11856}tckear id = 1 name = null appIdNamespace = {com.google.appengine.api.datastore.AppIdNamespace@11857}tckear checked = false raw = null serialisedSize = 128 cachedHashCode = 0 equalityPreferenceForInstance = true marshaller = {org.infinispan.marshall.CacheMarshaller@11829} entries = {org.infinispan.util.concurrent.BoundedConcurrentHashMap@11794} size = 3 [0] = {org.infinispan.util.concurrent.BoundedConcurrentHashMap$WriteThroughEntry@11833}MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 - MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 - MarshalledValue{instance= key: org.infinispan.marshall.MarshalledValue = {org.infinispan.marshall.MarshalledValue@11807}MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 value: org.infinispan.container.entries.ImmortalCacheEntry = {org.infinispan.container.entries.ImmortalCacheEntry@11808}MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 - MarshalledValue{instance=\n, serialized=false, cachedHashCode=112414304}@7c2aef8c [1] = {org.infinispan.util.concurrent.BoundedConcurrentHashMap$WriteThroughEntry@11835}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 - MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 - MarshalledValue{instance=\n, serialized=fa... key: org.infinispan.marshall.MarshalledValue = {org.infinispan.marshall.MarshalledValue@11811}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 instance = {com.google.appengine.api.datastore.Key@11671}Modules(1) parentKey = null kind = {java.lang.String@11855}Modules appId = {java.lang.String@11856}tckear id = 1 name = null appIdNamespace = {com.google.appengine.api.datastore.AppIdNamespace@11861}tckear checked = true raw = null serialisedSize = 128 cachedHashCode = 63491116 equalityPreferenceForInstance = true marshaller = {org.infinispan.marshall.CacheMarshaller@11829} value: org.infinispan.container.entries.ImmortalCacheEntry = {org.infinispan.container.entries.ImmortalCacheEntry@11812}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 - MarshalledValue{instance=\n, serialized=false, cachedHashCode=63491116}@1f7425f2 [2] = {org.infinispan.util.concurrent.BoundedConcurrentHashMap$WriteThroughEntry@11836}MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f - MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f - MarshalledValue{instance= key: org.infinispan.marshall.MarshalledValue = {org.infinispan.marshall.MarshalledValue@11815}MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f value: org.infinispan.container.entries.ImmortalCacheEntry = {org.infinispan.container.entries.ImmortalCacheEntry@11816}MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f - MarshalledValue{instance=\n, serialized=false, cachedHashCode=1413747955}@1d6779db ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] storeAsBinary + lookup
Forgot to mention: Put was done in 1st .war, where get is done in 2nd .war. @Test @InSequence(1) @OperateOnModule(m1) public void testPut() throws Exception { Key key = ds.put(new Entity(MODULES_KIND, 1)); Assert.assertNotNull(key); } @Test @InSequence(2) @OperateOnModule(m2) public void testGet() throws Exception { Key key = KeyFactory.createKey(MODULES_KIND, 1); Entity e = ds.get(key); Assert.assertNotNull(e); } -Ales On Aug 6, 2013, at 12:22 AM, Ales Justin ales.jus...@gmail.com wrote: Anything obvious on why this lookup doesn't find its match? Some background: * I have .ear, with 2 .war sub-deployments * each .war has own Key class in own gae.jar (in WEB-INF/lib) I do set storeAsBinary on the cache, which is shared between both .wars. This first key is the key for 2nd lookup. Below are entries of previous puts. As you can see, entry under [1] should match lookup key. But DataContainer returns null -- no match. -Ales --- key = {org.infinispan.marshall.MarshalledValue@11787}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=0}@8d2e9d9 instance = {com.google.appengine.api.datastore.Key@11063}Modules(1) parentKey = null kind = {java.lang.String@11855}Modules appId = {java.lang.String@11856}tckear id = 1 name = null appIdNamespace = {com.google.appengine.api.datastore.AppIdNamespace@11857}tckear checked = false raw = null serialisedSize = 128 cachedHashCode = 0 equalityPreferenceForInstance = true marshaller = {org.infinispan.marshall.CacheMarshaller@11829} entries = {org.infinispan.util.concurrent.BoundedConcurrentHashMap@11794} size = 3 [0] = {org.infinispan.util.concurrent.BoundedConcurrentHashMap$WriteThroughEntry@11833}MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 - MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 - MarshalledValue{instance= key: org.infinispan.marshall.MarshalledValue = {org.infinispan.marshall.MarshalledValue@11807}MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 value: org.infinispan.container.entries.ImmortalCacheEntry = {org.infinispan.container.entries.ImmortalCacheEntry@11808}MarshalledValue{instance=__namespace__(1), serialized=false, cachedHashCode=112414304}@3131088 - MarshalledValue{instance=\n, serialized=false, cachedHashCode=112414304}@7c2aef8c [1] = {org.infinispan.util.concurrent.BoundedConcurrentHashMap$WriteThroughEntry@11835}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 - MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 - MarshalledValue{instance=\n, serialized=fa... key: org.infinispan.marshall.MarshalledValue = {org.infinispan.marshall.MarshalledValue@11811}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 instance = {com.google.appengine.api.datastore.Key@11671}Modules(1) parentKey = null kind = {java.lang.String@11855}Modules appId = {java.lang.String@11856}tckear id = 1 name = null appIdNamespace = {com.google.appengine.api.datastore.AppIdNamespace@11861}tckear checked = true raw = null serialisedSize = 128 cachedHashCode = 63491116 equalityPreferenceForInstance = true marshaller = {org.infinispan.marshall.CacheMarshaller@11829} value: org.infinispan.container.entries.ImmortalCacheEntry = {org.infinispan.container.entries.ImmortalCacheEntry@11812}MarshalledValue{instance=Modules(1), serialized=false, cachedHashCode=63491116}@3134f207 - MarshalledValue{instance=\n, serialized=false, cachedHashCode=63491116}@1f7425f2 [2] = {org.infinispan.util.concurrent.BoundedConcurrentHashMap$WriteThroughEntry@11836}MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f - MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f - MarshalledValue{instance= key: org.infinispan.marshall.MarshalledValue = {org.infinispan.marshall.MarshalledValue@11815}MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f value: org.infinispan.container.entries.ImmortalCacheEntry = {org.infinispan.container.entries.ImmortalCacheEntry@11816}MarshalledValue{instance=__kind__(Modules), serialized=false, cachedHashCode=1413747955}@2ab5011f - MarshalledValue{instance=\n, serialized=false, cachedHashCode=1413747955}@1d6779db ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev