6 Replies Latest reply on May 29, 2014 1:43 AM by Bingu Shim

    Is this a bug?

    Bingu Shim Newbie

      Hello,

       

      I'm using Infinispan 6.0.2.Final with eviction=true, passivation=false and write-behind options

      With this configuration the changes(put,remove, etc.) are supposed to be queued and stored asynchronously.

      and, duplicated modification for same key will be merged, and stored just once.

       

      However, this is not what I have observed.

       

      And here is what I found so far.

       

      I ran a test code that contain a for loop which put random value of a key named "KEY".

      Then, I counted the number of db store operations, it was exactly 1000.(which means no merging operation happened)

       

      Here is the test code.

         private static void startTest() {
            for(int i=0; i<1000; i++) {
               cache.put("KEY", generateValue(1024*1024));
            }
         }
         static Random random = new Random(System.currentTimeMillis());
         private static byte[] generateValue(int size) {
            byte[] result = new byte[size];
            random.nextBytes(result);
            return result;
         }
      
      
      

       

       

      Then I did some more test by modifying the infinispan-core source.

       

      I checked the size of org.infinispan.persistence.async.State.modifications and it was increased whenever cache.put() operation called.

      It was because the ConcurrentMap<Object, Modification> for the org.infinispan.persistence.async.State.modifications variable cannot distinguish byte[] type as key.

      (I guess this is becuase the AnyEquivalence object for the map is for 'Object' type, hence cannot distinguish byte[] key.)

       

      The following is where the ConcurrentMap<Object, Modification> is created.

      package org.infinispan.persistence.async;
      
      import net.jcip.annotations.GuardedBy;
      
      public class AsyncCacheWriter extends DelegatingCacheWriter {
         ....
         State newState(boolean clear, State next) {
            ConcurrentMap<Object, Modification> map = CollectionFactory.makeConcurrentMap(64, concurrencyLevel);  <- EquivalentConcurrentHashMapV8 returned.
            return new State(clear, map, next);
         }
         ....
      }
      
      
      

       

       

      Is this normal operation? or a bug?

       

      If this is normal, it could cause serious performance and memory problem..

        • 1. Re: Is this a bug?
          Wolf-Dieter Fink Master

          Not sure whether you can expect merge.

          Maybe the write is too fast or you run in the write-through mode, see modification-queue-size

          • 2. Re: Re: Is this a bug?
            Bingu Shim Newbie

            Hi Wolf-Dieter,

             

            Thank you for your reply.

             

            I run the test with 'write-through' mode and modification-queue-size of 10000.

            I think I can expect merge, according to the description of org.infinispan.persistence.async.AsyncCacheWriter class.

            It saids as follow.(at Ver. 6.0.2.Final)

             

            Write operations affecting same key are now coalesced so that only the final state is actually stored.

             

            However what I observed is it writes all changes of one key.

            I don't think this is because it writes too fast.

            Even though the write is too fast, at least some of changes have to be merged, I guess.

            But, there was no merge(coalesced??) happened.

             

            I think this is a bug. caused by CollectionFactory.makeConcurrentMap() method which returns wrong ConcurrentMap.(cannot handle byte[] key.)

            • 3. Re: Re: Is this a bug?
              William Burns Expert

              I am assuming since you are passing a String and are talking about the key being a byte[] that you are using a remote client such as HotRod.

               

              Looking at the AsyncCacheWriter it always uses a Map that doesn't allow for the Key Equivalence to be provided.  In this case using a Key type that doesn't work properly for equality will not work for the merging,such as byte[].  Please log a bug, as we need to make sure the configured Key Equivalence is used for the Map provided to the State instance as well.

               

              If you enable compatibility mode for the server, it should allow this to work since the key will be changed back to the String when storing, but this will reduce overall performance a bit.

              1 of 1 people found this helpful
              • 4. Re: Is this a bug?
                Bingu Shim Newbie

                Yes you are right, I'm using remote client and passing a String as a key.

                 

                Here is what I found so far.

                 

                I have debugged and find out that the Key Equivalence used by Map of State class is 'org.infinispan.commons.equivalence.AnyEquivalence' which can only handle Object and primitive type key but cannot handle byte[] key.

                However, 'org.jboss.as.clustering.infinispan.equivalence.AnyServerEquivalence' class can handle both Object and byte[] key.

                This Key Equivalence is used by 'org.infinispan.util.concurrent.BoundedConcurrentHashMap' class which is the core data structure of infinispan, and it contains all in memory entries.

                 

                So, I changed CollectionFactory.makeConcurrentMap() method to use AnyServerEquivalence.

                Then, the problem solved(duplicated key is now merged and only the last change is stored to the cache store.)

                 

                I'm just wondering If this solution is right? or not?

                 

                Thank you.

                • 5. Re: Is this a bug?
                  William Burns Expert

                  It is similar to the solution, but not quite.  The full fix would use the key Equivalence defined on the DataContainerConfiguration instead of hard coding it to a specific implementation.

                   

                  If you watend to submit a PR/Jira with the fixes that would be great! Thanks!

                  • 6. Re: Is this a bug?
                    Bingu Shim Newbie

                    Thank you for your answer William.

                     

                    It is really helpful.

                     

                    About the fix, I really would like, but I don't know how to submit a PR/Jira with fixes right now.

                     

                    This weekend, I'll study about it and hopefully submit.

                     

                    Thanks