ignite-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Alexandr Kuramshin (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (IGNITE-4293) Deserialized value is cached if queries are enabled
Date Thu, 15 Dec 2016 10:20:58 GMT

    [ https://issues.apache.org/jira/browse/IGNITE-4293?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15751001#comment-15751001

Alexandr Kuramshin commented on IGNITE-4293:

Let's look at the basis with two types: CacheObject and CacheObjectContext.

Because the implementations could be very different, let's think abstract.

Calling CacheObject.value(CacheObjectContext ctx, boolean cpy) we'll get a user object independently
of underlying storage and implementation.

Supposed that the CacheObject MAY have a cached instance of the user object on-heap, and the
{cpy} flag is like a hint controlling behaivor of such implementations. If it's true, then
the copy of the user object MAY be returned, if underlying CacheObject have the such internal
on-heap instance, but if it's false is also possible to retreive a new instance every time
because of absence of internal field.

Next there is CacheObjectContext controlling the behavior of the caching on-heap instance
and user objects will be returned. Precisely two methods: copyOnGet() and storeValue().

Supposed that copyOnGet() value controls behaviour of CacheObjects with respect to {cpy} flag.
If copyOnGet() is false, then the cached user object should be returned, if the internal on-heap
instance is present. And if storeValue() is true, then the CacheObject should store the user
object upon deserialization, if the internal field is present.

It's seems that copyOnGet() and storeValue() are threated independently, but it's something
wrong. If we'll call every time CacheObject.value(ctx, true) and both ctx.copyOnGet() and
ctx.storeValue() are true, then the stored value will never be used. But relating to common
usage of CacheObject.value method it's seems that usual value of {cpy} is false, so the problem
is virtual.

I'm wondering that nothing of above was written in Javadoc.

Going further, I'm answering myself when the copyOnGet() and storeValue() should be true or

Definitly they should depend upon user preference CacheConfiguration.isCopyOnRead(): copyOnGet()
== isCopyOnRead(); storeValue() != isCopyOnRead().

Also we should take in account how indexing are working. Whenever indexing is enabled on the
cache, some number of GridH2ValueCacheObject are present (up to number of cache entries).
There is the method GridH2ValueCacheObject.compareSecure(Value v, CompareMode mode) which
compares the two CacheObject or its serialized user objects, depending of the CacheObject.isPlatformType()
value. So, because compareSecure() method is time critical, we should set storeValue() to
true, when indexing is enabled AND CacheObject.isPlatformType() is true for all entries in
the cache, to avoid high CPU overhead upon deserializing user object on each compareSecure()

Actual CacheObject type stored in the cache depends on the IgniteConfiguration.getMarshaller()
value configured. The GridQueryProcessor.isEnabled(CacheConfiguration ccfg) doesn't take into
account what marshaller type is used, but only whether indexing is enabled. It should be fixed.

There is another condition IgniteConfiguration.isPeerClassLoadingEnabled() is used to determine
CacheObjectContext.storeValue(). It is still being discovered.

> Deserialized value is cached if queries are enabled
> ---------------------------------------------------
>                 Key: IGNITE-4293
>                 URL: https://issues.apache.org/jira/browse/IGNITE-4293
>             Project: Ignite
>          Issue Type: Bug
>          Components: cache
>    Affects Versions: 1.7
>            Reporter: Valentin Kulichenko
>            Priority: Critical
> Here is the problematic piece of code in {{IgniteCacheObjectProcessorImpl}}:
> {code}
> boolean storeVal = ctx.config().isPeerClassLoadingEnabled() ||
>     GridQueryProcessor.isEnabled(ccfg) ||
>     !ccfg.isCopyOnRead();
> {code}
> This flag is set to true if queries are enabled even when binary marshaller is used (this
condition makes sense to other marshallers though). It is then use in {{BinaryObjectImpl.deserializeValue}}:
> {code}
> if (coCtx != null && coCtx.storeValue())
>     obj = obj0;
> {code}
> As a result, memory consumption doubles.

This message was sent by Atlassian JIRA

View raw message