Quantcast

Effective size limit for cache items in Ignite

classic Classic list List threaded Threaded
6 messages Options
Raymond Wilson Raymond Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Effective size limit for cache items in Ignite

Hi,

 

What is the practical size limit for items in an Ignite cache?

 

I suspect the answer is something “As large as the memory you have to hold it”, but my question is more aimed at the practicality of large items in a cache due to the overhead of pulling copies of the items out of the cache in response to a Cache.Get() request.

 

For instance, let’s say I had cache items in the 64Kb size range, and had requests that commonly refer to those cache items to perform some work on them in response to a request. Will each Cache.Get() request require an extraction and repackaging of the cache item prior to handing it back to the caller as a new (copied) version of that cache item, or is there a way for just a reference to the cache item to be returned to the caller?

 

I understand there is a way to designate the information in a cache as just blobs of data with no serialisation semantics. In this case does a Cache.Get() return a pointer or a copy (with a local locking semantic to prevent change)?

 

Thanks,

Raymond.

 

Raymond Wilson Raymond Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Effective size limit for cache items in Ignite

Ah, I found the CopyOnRead flag in the cache configuration.

 

Unfortunately, it seems to have the same behaviour regardless of the setting for this flag.

 

If I create an example like the below, it seems that querying the same element from the cache many times takes about the same amount of time in both cases. Visual Studio also reports large numbers of GC episodes while it cleans up the large freed MyCacheClass instances. Is this flag only applicable to Java contexts? I did also try setting KeepBinaryInStore to true, though there was no noticeable difference.

 

[Serializable]

    public class MyCacheClass

    {

        public String name = String.Empty;

        private byte[] localData = null;

 

        public MyCacheClass(String _name)

        {

            name = _name;

            localData = new byte[4000000];

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            IIgnite ignite = Ignition.Start();

 

            // Add a cache to Ignite

            ICache<String, MyCacheClass> cache = ignite.CreateCache<String, MyCacheClass>

                (new CacheConfiguration()

                {

                    Name = "TestCache",

                    CopyOnRead = false,

                    KeepBinaryInStore = true

                });

 

            // Add a cache item

            cache.Put("First", new MyCacheClass("FirstItem"));

 

            // query back the cache items

            for (int i = 0; i < 30000; i++)

            {

                MyCacheClass first = cache.Get("First");

            }

      }

 

 

From: Raymond Wilson [mailto:[hidden email]]
Sent: Monday, February 13, 2017 11:35 AM
To: [hidden email]
Subject: Effective size limit for cache items in Ignite

 

Hi,

 

What is the practical size limit for items in an Ignite cache?

 

I suspect the answer is something “As large as the memory you have to hold it”, but my question is more aimed at the practicality of large items in a cache due to the overhead of pulling copies of the items out of the cache in response to a Cache.Get() request.

 

For instance, let’s say I had cache items in the 64Kb size range, and had requests that commonly refer to those cache items to perform some work on them in response to a request. Will each Cache.Get() request require an extraction and repackaging of the cache item prior to handing it back to the caller as a new (copied) version of that cache item, or is there a way for just a reference to the cache item to be returned to the caller?

 

I understand there is a way to designate the information in a cache as just blobs of data with no serialisation semantics. In this case does a Cache.Get() return a pointer or a copy (with a local locking semantic to prevent change)?

 

Thanks,

Raymond.

 

Raymond Wilson Raymond Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Effective size limit for cache items in Ignite

In reply to this post by Raymond Wilson

I found this code snippet in the Ignite v1.8 source:

 

This appears to be the core place where the value of CopyOnRead has an effect, though I don’t understand the context of the other logical conditions around it; it seems that CopyOnRead is dependent on other configuration state before it will be honoured. I’m still digging to locate the detailed help around this setting to understand these other conditions.

    /** {@inheritDoc} */

    @Override public CacheObjectContext contextForCache(CacheConfiguration ccfg) throws IgniteCheckedException {

        assert ccfg != null;

 

        CacheMemoryMode memMode = ccfg.getMemoryMode();

 

        boolean storeVal = !ccfg.isCopyOnRead() || (!isBinaryEnabled(ccfg) &&

            (GridQueryProcessor.isEnabled(ccfg) || ctx.config().isPeerClassLoadingEnabled()));

 

        CacheObjectContext res = new CacheObjectContext(ctx,

            ccfg.getName(),

            ccfg.getAffinityMapper() != null ? ccfg.getAffinityMapper() : new GridCacheDefaultAffinityKeyMapper(),

            ccfg.isCopyOnRead() && memMode != OFFHEAP_VALUES,

            storeVal,

            ctx.config().isPeerClassLoadingEnabled() && !isBinaryEnabled(ccfg));

 

        ctx.resource().injectGeneric(res.defaultAffMapper());

 

        return res;

    }

 

Thanks,

Raymond.

 

From: Raymond Wilson [mailto:[hidden email]]
Sent: Monday, February 13, 2017 2:43 PM
To: [hidden email]
Subject: RE: Effective size limit for cache items in Ignite

 

Ah, I found the CopyOnRead flag in the cache configuration.

 

Unfortunately, it seems to have the same behaviour regardless of the setting for this flag.

 

If I create an example like the below, it seems that querying the same element from the cache many times takes about the same amount of time in both cases. Visual Studio also reports large numbers of GC episodes while it cleans up the large freed MyCacheClass instances. Is this flag only applicable to Java contexts? I did also try setting KeepBinaryInStore to true, though there was no noticeable difference.

 

[Serializable]

    public class MyCacheClass

    {

        public String name = String.Empty;

        private byte[] localData = null;

 

        public MyCacheClass(String _name)

        {

            name = _name;

            localData = new byte[4000000];

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            IIgnite ignite = Ignition.Start();

 

            // Add a cache to Ignite

            ICache<String, MyCacheClass> cache = ignite.CreateCache<String, MyCacheClass>

                (new CacheConfiguration()

                {

                    Name = "TestCache",

                    CopyOnRead = false,

                    KeepBinaryInStore = true

                });

 

            // Add a cache item

            cache.Put("First", new MyCacheClass("FirstItem"));

 

            // query back the cache items

            for (int i = 0; i < 30000; i++)

            {

                MyCacheClass first = cache.Get("First");

            }

      }

 

 

From: Raymond Wilson [[hidden email]]
Sent: Monday, February 13, 2017 11:35 AM
To: [hidden email]
Subject: Effective size limit for cache items in Ignite

 

Hi,

 

What is the practical size limit for items in an Ignite cache?

 

I suspect the answer is something “As large as the memory you have to hold it”, but my question is more aimed at the practicality of large items in a cache due to the overhead of pulling copies of the items out of the cache in response to a Cache.Get() request.

 

For instance, let’s say I had cache items in the 64Kb size range, and had requests that commonly refer to those cache items to perform some work on them in response to a request. Will each Cache.Get() request require an extraction and repackaging of the cache item prior to handing it back to the caller as a new (copied) version of that cache item, or is there a way for just a reference to the cache item to be returned to the caller?

 

I understand there is a way to designate the information in a cache as just blobs of data with no serialisation semantics. In this case does a Cache.Get() return a pointer or a copy (with a local locking semantic to prevent change)?

 

Thanks,

Raymond.

 

ptupitsyn ptupitsyn
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Effective size limit for cache items in Ignite

Hi Raymond,

CopyOnRead setting has no effect in .NET code.
It exists for cases when there are both Java and .NET nodes in a cluster.

In Ignite.NET each cache.Get call causes two things:
1) Copy a piece of memory from Java (serialized data)
2) Deserialize the data into user type instance.

You can avoid deserialization by using Binary Mode:

Pavel

On Mon, Feb 13, 2017 at 6:38 AM, Raymond Wilson <[hidden email]> wrote:

I found this code snippet in the Ignite v1.8 source:

 

This appears to be the core place where the value of CopyOnRead has an effect, though I don’t understand the context of the other logical conditions around it; it seems that CopyOnRead is dependent on other configuration state before it will be honoured. I’m still digging to locate the detailed help around this setting to understand these other conditions.

    /** {@inheritDoc} */

    @Override public CacheObjectContext contextForCache(CacheConfiguration ccfg) throws IgniteCheckedException {

        assert ccfg != null;

 

        CacheMemoryMode memMode = ccfg.getMemoryMode();

 

        boolean storeVal = !ccfg.isCopyOnRead() || (!isBinaryEnabled(ccfg) &&

            (GridQueryProcessor.isEnabled(ccfg) || ctx.config().isPeerClassLoadingEnabled()));

 

        CacheObjectContext res = new CacheObjectContext(ctx,

            ccfg.getName(),

            ccfg.getAffinityMapper() != null ? ccfg.getAffinityMapper() : new GridCacheDefaultAffinityKeyMapper(),

            ccfg.isCopyOnRead() && memMode != OFFHEAP_VALUES,

            storeVal,

            ctx.config().isPeerClassLoadingEnabled() && !isBinaryEnabled(ccfg));

 

        ctx.resource().injectGeneric(res.defaultAffMapper());

 

        return res;

    }

 

Thanks,

Raymond.

 

From: Raymond Wilson [mailto:[hidden email]]
Sent: Monday, February 13, 2017 2:43 PM
To: [hidden email]
Subject: RE: Effective size limit for cache items in Ignite

 

Ah, I found the CopyOnRead flag in the cache configuration.

 

Unfortunately, it seems to have the same behaviour regardless of the setting for this flag.

 

If I create an example like the below, it seems that querying the same element from the cache many times takes about the same amount of time in both cases. Visual Studio also reports large numbers of GC episodes while it cleans up the large freed MyCacheClass instances. Is this flag only applicable to Java contexts? I did also try setting KeepBinaryInStore to true, though there was no noticeable difference.

 

[Serializable]

    public class MyCacheClass

    {

        public String name = String.Empty;

        private byte[] localData = null;

 

        public MyCacheClass(String _name)

        {

            name = _name;

            localData = new byte[4000000];

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            IIgnite ignite = Ignition.Start();

 

            // Add a cache to Ignite

            ICache<String, MyCacheClass> cache = ignite.CreateCache<String, MyCacheClass>

                (new CacheConfiguration()

                {

                    Name = "TestCache",

                    CopyOnRead = false,

                    KeepBinaryInStore = true

                });

 

            // Add a cache item

            cache.Put("First", new MyCacheClass("FirstItem"));

 

            // query back the cache items

            for (int i = 0; i < 30000; i++)

            {

                MyCacheClass first = cache.Get("First");

            }

      }

 

 

From: Raymond Wilson [[hidden email]]
Sent: Monday, February 13, 2017 11:35 AM
To: [hidden email]
Subject: Effective size limit for cache items in Ignite

 

Hi,

 

What is the practical size limit for items in an Ignite cache?

 

I suspect the answer is something “As large as the memory you have to hold it”, but my question is more aimed at the practicality of large items in a cache due to the overhead of pulling copies of the items out of the cache in response to a Cache.Get() request.

 

For instance, let’s say I had cache items in the 64Kb size range, and had requests that commonly refer to those cache items to perform some work on them in response to a request. Will each Cache.Get() request require an extraction and repackaging of the cache item prior to handing it back to the caller as a new (copied) version of that cache item, or is there a way for just a reference to the cache item to be returned to the caller?

 

I understand there is a way to designate the information in a cache as just blobs of data with no serialisation semantics. In this case does a Cache.Get() return a pointer or a copy (with a local locking semantic to prevent change)?

 

Thanks,

Raymond.

 


Raymond Wilson Raymond Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Effective size limit for cache items in Ignite

Hi Pavel,

 

Thanks for the clarification.

 

Just curious: If CopyOnRead has no effect in .Net, why is it exposed in the .Net API?

 

It sounds like if my code was Java, rather than c#, setting CopyOnRead result in an object reference being passed to the client with no transmission of data and no deserialization overhead, even if not using Binary Mode, is that correct? This suggests a pretty significant performance penalty if you’re using the .Net API and suggests ‘heavy-lift’ aspects of a solution would be much more performant if implemented in Java. Is that correct?

 

My reason for asking is that I have workflows that might access 10’s of thousands of cached items where each cached item could be several Kb in size and where responses are returned in 200-300 of milliseconds. Some quick finger in the air tests indicate the deserialization overhead alone by using a .Net client (at least for those workflows) is much longer than that.

 

Thanks,

Raymond.

 

From: Pavel Tupitsyn [mailto:[hidden email]]
Sent: Tuesday, February 14, 2017 2:16 AM
To: [hidden email]
Subject: Re: Effective size limit for cache items in Ignite

 

Hi Raymond,

 

CopyOnRead setting has no effect in .NET code.

It exists for cases when there are both Java and .NET nodes in a cluster.

 

In Ignite.NET each cache.Get call causes two things:

1) Copy a piece of memory from Java (serialized data)

2) Deserialize the data into user type instance.

 

You can avoid deserialization by using Binary Mode:

 

Pavel

 

On Mon, Feb 13, 2017 at 6:38 AM, Raymond Wilson <[hidden email]> wrote:

I found this code snippet in the Ignite v1.8 source:

 

This appears to be the core place where the value of CopyOnRead has an effect, though I don’t understand the context of the other logical conditions around it; it seems that CopyOnRead is dependent on other configuration state before it will be honoured. I’m still digging to locate the detailed help around this setting to understand these other conditions.

    /** {@inheritDoc} */

    @Override public CacheObjectContext contextForCache(CacheConfiguration ccfg) throws IgniteCheckedException {

        assert ccfg != null;

 

        CacheMemoryMode memMode = ccfg.getMemoryMode();

 

        boolean storeVal = !ccfg.isCopyOnRead() || (!isBinaryEnabled(ccfg) &&

            (GridQueryProcessor.isEnabled(ccfg) || ctx.config().isPeerClassLoadingEnabled()));

 

        CacheObjectContext res = new CacheObjectContext(ctx,

            ccfg.getName(),

            ccfg.getAffinityMapper() != null ? ccfg.getAffinityMapper() : new GridCacheDefaultAffinityKeyMapper(),

            ccfg.isCopyOnRead() && memMode != OFFHEAP_VALUES,

            storeVal,

            ctx.config().isPeerClassLoadingEnabled() && !isBinaryEnabled(ccfg));

 

        ctx.resource().injectGeneric(res.defaultAffMapper());

 

        return res;

    }

 

Thanks,

Raymond.

 

From: Raymond Wilson [mailto:[hidden email]]
Sent: Monday, February 13, 2017 2:43 PM
To: [hidden email]
Subject: RE: Effective size limit for cache items in Ignite

 

Ah, I found the CopyOnRead flag in the cache configuration.

 

Unfortunately, it seems to have the same behaviour regardless of the setting for this flag.

 

If I create an example like the below, it seems that querying the same element from the cache many times takes about the same amount of time in both cases. Visual Studio also reports large numbers of GC episodes while it cleans up the large freed MyCacheClass instances. Is this flag only applicable to Java contexts? I did also try setting KeepBinaryInStore to true, though there was no noticeable difference.

 

[Serializable]

    public class MyCacheClass

    {

        public String name = String.Empty;

        private byte[] localData = null;

 

        public MyCacheClass(String _name)

        {

            name = _name;

            localData = new byte[4000000];

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            IIgnite ignite = Ignition.Start();

 

            // Add a cache to Ignite

            ICache<String, MyCacheClass> cache = ignite.CreateCache<String, MyCacheClass>

                (new CacheConfiguration()

                {

                    Name = "TestCache",

                    CopyOnRead = false,

                    KeepBinaryInStore = true

                });

 

            // Add a cache item

            cache.Put("First", new MyCacheClass("FirstItem"));

 

            // query back the cache items

            for (int i = 0; i < 30000; i++)

            {

                MyCacheClass first = cache.Get("First");

            }

      }

 

 

From: Raymond Wilson [[hidden email]]
Sent: Monday, February 13, 2017 11:35 AM
To: [hidden email]
Subject: Effective size limit for cache items in Ignite

 

Hi,

 

What is the practical size limit for items in an Ignite cache?

 

I suspect the answer is something “As large as the memory you have to hold it”, but my question is more aimed at the practicality of large items in a cache due to the overhead of pulling copies of the items out of the cache in response to a Cache.Get() request.

 

For instance, let’s say I had cache items in the 64Kb size range, and had requests that commonly refer to those cache items to perform some work on them in response to a request. Will each Cache.Get() request require an extraction and repackaging of the cache item prior to handing it back to the caller as a new (copied) version of that cache item, or is there a way for just a reference to the cache item to be returned to the caller?

 

I understand there is a way to designate the information in a cache as just blobs of data with no serialisation semantics. In this case does a Cache.Get() return a pointer or a copy (with a local locking semantic to prevent change)?

 

Thanks,

Raymond.

 

 

ptupitsyn ptupitsyn
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Effective size limit for cache items in Ignite

If CopyOnRead has no effect in .Net, why is it exposed in the .Net API?

It may be useful when Java and .NET nodes work together in one cluster.
For example, you may want to start cache from .NET, but use it in Java as well.

Ignite.NET is built on top of Ignite Java. We start JVM in process.
So yes, Ignite.NET API always has some overhead (JNI calls, data copying).

However, in real-world scenarios this overhead is usually minor.
For example, according to some becnhmarks I did, doing put & get of a simple
user object with 4 nodes on 4 machines is ~5% slower in .NET than in Java.

Of course, this depends a lot on how your objects look, your cluster setup,
and many other things. The only way to know is to measure your exact scenario.


if my code was Java, rather than c#, setting CopyOnRead result in an object reference being passed to the client with no transmission of data and no deserialization overhead, even if not using Binary Mode, is that correct

In some cases yes (if that object is not on another node and not in offheap memory).

On Tue, Feb 14, 2017 at 12:51 AM, Raymond Wilson <[hidden email]> wrote:

Hi Pavel,

 

Thanks for the clarification.

 

Just curious: If CopyOnRead has no effect in .Net, why is it exposed in the .Net API?

 

It sounds like if my code was Java, rather than c#, setting CopyOnRead result in an object reference being passed to the client with no transmission of data and no deserialization overhead, even if not using Binary Mode, is that correct? This suggests a pretty significant performance penalty if you’re using the .Net API and suggests ‘heavy-lift’ aspects of a solution would be much more performant if implemented in Java. Is that correct?

 

My reason for asking is that I have workflows that might access 10’s of thousands of cached items where each cached item could be several Kb in size and where responses are returned in 200-300 of milliseconds. Some quick finger in the air tests indicate the deserialization overhead alone by using a .Net client (at least for those workflows) is much longer than that.

 

Thanks,

Raymond.

 

From: Pavel Tupitsyn [mailto:[hidden email]]
Sent: Tuesday, February 14, 2017 2:16 AM
To: [hidden email]
Subject: Re: Effective size limit for cache items in Ignite

 

Hi Raymond,

 

CopyOnRead setting has no effect in .NET code.

It exists for cases when there are both Java and .NET nodes in a cluster.

 

In Ignite.NET each cache.Get call causes two things:

1) Copy a piece of memory from Java (serialized data)

2) Deserialize the data into user type instance.

 

You can avoid deserialization by using Binary Mode:

 

Pavel

 

On Mon, Feb 13, 2017 at 6:38 AM, Raymond Wilson <[hidden email]> wrote:

I found this code snippet in the Ignite v1.8 source:

 

This appears to be the core place where the value of CopyOnRead has an effect, though I don’t understand the context of the other logical conditions around it; it seems that CopyOnRead is dependent on other configuration state before it will be honoured. I’m still digging to locate the detailed help around this setting to understand these other conditions.

    /** {@inheritDoc} */

    @Override public CacheObjectContext contextForCache(CacheConfiguration ccfg) throws IgniteCheckedException {

        assert ccfg != null;

 

        CacheMemoryMode memMode = ccfg.getMemoryMode();

 

        boolean storeVal = !ccfg.isCopyOnRead() || (!isBinaryEnabled(ccfg) &&

            (GridQueryProcessor.isEnabled(ccfg) || ctx.config().isPeerClassLoadingEnabled()));

 

        CacheObjectContext res = new CacheObjectContext(ctx,

            ccfg.getName(),

            ccfg.getAffinityMapper() != null ? ccfg.getAffinityMapper() : new GridCacheDefaultAffinityKeyMapper(),

            ccfg.isCopyOnRead() && memMode != OFFHEAP_VALUES,

            storeVal,

            ctx.config().isPeerClassLoadingEnabled() && !isBinaryEnabled(ccfg));

 

        ctx.resource().injectGeneric(res.defaultAffMapper());

 

        return res;

    }

 

Thanks,

Raymond.

 

From: Raymond Wilson [mailto:[hidden email]]
Sent: Monday, February 13, 2017 2:43 PM
To: [hidden email]
Subject: RE: Effective size limit for cache items in Ignite

 

Ah, I found the CopyOnRead flag in the cache configuration.

 

Unfortunately, it seems to have the same behaviour regardless of the setting for this flag.

 

If I create an example like the below, it seems that querying the same element from the cache many times takes about the same amount of time in both cases. Visual Studio also reports large numbers of GC episodes while it cleans up the large freed MyCacheClass instances. Is this flag only applicable to Java contexts? I did also try setting KeepBinaryInStore to true, though there was no noticeable difference.

 

[Serializable]

    public class MyCacheClass

    {

        public String name = String.Empty;

        private byte[] localData = null;

 

        public MyCacheClass(String _name)

        {

            name = _name;

            localData = new byte[4000000];

        }

    }

 

    class Program

    {

        static void Main(string[] args)

        {

            IIgnite ignite = Ignition.Start();

 

            // Add a cache to Ignite

            ICache<String, MyCacheClass> cache = ignite.CreateCache<String, MyCacheClass>

                (new CacheConfiguration()

                {

                    Name = "TestCache",

                    CopyOnRead = false,

                    KeepBinaryInStore = true

                });

 

            // Add a cache item

            cache.Put("First", new MyCacheClass("FirstItem"));

 

            // query back the cache items

            for (int i = 0; i < 30000; i++)

            {

                MyCacheClass first = cache.Get("First");

            }

      }

 

 

From: Raymond Wilson [[hidden email]]
Sent: Monday, February 13, 2017 11:35 AM
To: [hidden email]
Subject: Effective size limit for cache items in Ignite

 

Hi,

 

What is the practical size limit for items in an Ignite cache?

 

I suspect the answer is something “As large as the memory you have to hold it”, but my question is more aimed at the practicality of large items in a cache due to the overhead of pulling copies of the items out of the cache in response to a Cache.Get() request.

 

For instance, let’s say I had cache items in the 64Kb size range, and had requests that commonly refer to those cache items to perform some work on them in response to a request. Will each Cache.Get() request require an extraction and repackaging of the cache item prior to handing it back to the caller as a new (copied) version of that cache item, or is there a way for just a reference to the cache item to be returned to the caller?

 

I understand there is a way to designate the information in a cache as just blobs of data with no serialisation semantics. In this case does a Cache.Get() return a pointer or a copy (with a local locking semantic to prevent change)?

 

Thanks,

Raymond.

 

 


Loading...