Cache Groups

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Cache Groups

Lon Varscsak
Hey all,

I’ve been using cache groups to do refreshing of object lists and it
occurred to me today that this refresh is across all object contexts in my
application.  So if User A has a list of orders for their account and that
is cached with the group “orderHistory” and User B also has a list of
orders in “orderHistory”, running a refresh query will result in ALL users
refreshing their orderHistory caches.

I’m not sure that this is what I want.  How have you solved this
situation?  Do you care? :P  I was thinking about doing something like
WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware of.

Any feedback is appreciated.

-Lon
Reply | Threaded
Open this post in threaded view
|

Re: Cache Groups

Musall, Maik
Hi Lon,

have you read this? https://cayenne.apache.org/docs/4.0/cayenne-guide/performance-tuning.html#turning-off-synchronization-of-objectcontexts <https://cayenne.apache.org/docs/4.0/cayenne-guide/performance-tuning.html#turning-off-synchronization-of-objectcontexts>

I added this module to my server runtime builder (stripped down to the relevant bit for this discussion):

Module cachePropertiesModule = new Module() {
        @Override
        public void configure( Binder binder ) {
                MapBuilder<String> props = binder.bindMap( String.class, Constants.PROPERTIES_MAP );
                props.put( Constants.SERVER_CONTEXTS_SYNC_PROPERTY, "false" );
        }
};

Maik


> Am 08.11.2017 um 01:40 schrieb Lon Varscsak <[hidden email]>:
>
> Hey all,
>
> I’ve been using cache groups to do refreshing of object lists and it
> occurred to me today that this refresh is across all object contexts in my
> application.  So if User A has a list of orders for their account and that
> is cached with the group “orderHistory” and User B also has a list of
> orders in “orderHistory”, running a refresh query will result in ALL users
> refreshing their orderHistory caches.
>
> I’m not sure that this is what I want.  How have you solved this
> situation?  Do you care? :P  I was thinking about doing something like
> WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware of.
>
> Any feedback is appreciated.
>
> -Lon

Reply | Threaded
Open this post in threaded view
|

Re: Cache Groups

Lon Varscsak
Yeah, I’m not syncing between contexts (as much as I’d like to :P)…this is
about query caches.

On Wed, Nov 8, 2017 at 3:56 AM, Musall, Maik <[hidden email]> wrote:

> Hi Lon,
>
> have you read this? https://cayenne.apache.org/docs/4.0/cayenne-guide/
> performance-tuning.html#turning-off-synchronization-of-objectcontexts <
> https://cayenne.apache.org/docs/4.0/cayenne-guide/performance-tuning.html#
> turning-off-synchronization-of-objectcontexts>
>
> I added this module to my server runtime builder (stripped down to the
> relevant bit for this discussion):
>
> Module cachePropertiesModule = new Module() {
>         @Override
>         public void configure( Binder binder ) {
>                 MapBuilder<String> props = binder.bindMap( String.class,
> Constants.PROPERTIES_MAP );
>                 props.put( Constants.SERVER_CONTEXTS_SYNC_PROPERTY,
> "false" );
>         }
> };
>
> Maik
>
>
> > Am 08.11.2017 um 01:40 schrieb Lon Varscsak <[hidden email]>:
> >
> > Hey all,
> >
> > I’ve been using cache groups to do refreshing of object lists and it
> > occurred to me today that this refresh is across all object contexts in
> my
> > application.  So if User A has a list of orders for their account and
> that
> > is cached with the group “orderHistory” and User B also has a list of
> > orders in “orderHistory”, running a refresh query will result in ALL
> users
> > refreshing their orderHistory caches.
> >
> > I’m not sure that this is what I want.  How have you solved this
> > situation?  Do you care? :P  I was thinking about doing something like
> > WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware of.
> >
> > Any feedback is appreciated.
> >
> > -Lon
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Cache Groups

John Huss
Yes, invalidating the cache group will remove the cached data for all users
or query parameters, etc. It's not great.  You can make the cache group
more specific (like by adding a username or something to it) and that will
work, but you'll need to have these cache names configured in your cache
provider already or have a default that makes sense.  That might be
difficult to do.

I'm interested to hear how others handle this.  I see this being a fairly
big limitation of the query cache.

On Wed, Nov 8, 2017 at 11:23 AM Lon Varscsak <[hidden email]> wrote:

> Yeah, I’m not syncing between contexts (as much as I’d like to :P)…this is
> about query caches.
>
> On Wed, Nov 8, 2017 at 3:56 AM, Musall, Maik <[hidden email]> wrote:
>
> > Hi Lon,
> >
> > have you read this? https://cayenne.apache.org/docs/4.0/cayenne-guide/
> > performance-tuning.html#turning-off-synchronization-of-objectcontexts <
> >
> https://cayenne.apache.org/docs/4.0/cayenne-guide/performance-tuning.html#
> > turning-off-synchronization-of-objectcontexts>
> >
> > I added this module to my server runtime builder (stripped down to the
> > relevant bit for this discussion):
> >
> > Module cachePropertiesModule = new Module() {
> >         @Override
> >         public void configure( Binder binder ) {
> >                 MapBuilder<String> props = binder.bindMap( String.class,
> > Constants.PROPERTIES_MAP );
> >                 props.put( Constants.SERVER_CONTEXTS_SYNC_PROPERTY,
> > "false" );
> >         }
> > };
> >
> > Maik
> >
> >
> > > Am 08.11.2017 um 01:40 schrieb Lon Varscsak <[hidden email]>:
> > >
> > > Hey all,
> > >
> > > I’ve been using cache groups to do refreshing of object lists and it
> > > occurred to me today that this refresh is across all object contexts in
> > my
> > > application.  So if User A has a list of orders for their account and
> > that
> > > is cached with the group “orderHistory” and User B also has a list of
> > > orders in “orderHistory”, running a refresh query will result in ALL
> > users
> > > refreshing their orderHistory caches.
> > >
> > > I’m not sure that this is what I want.  How have you solved this
> > > situation?  Do you care? :P  I was thinking about doing something like
> > > WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware of.
> > >
> > > Any feedback is appreciated.
> > >
> > > -Lon
> >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Cache Groups

Andrus Adamchik
"Cooperating" cache with shared cache groups decreases *average* DB load and improves performance on *average*. The assumption is that the app can afford to execute each individual DB query in isolation, and is mostly concerned with overall load. If you have multiple queries within the same request, some may need a refresh, some others may still be cached, with the overall performance still being acceptable. If the individual queries are too slow, you'd often be able to improve things with DB indexes.

So I strongly recommend trying the above approach in a real app before you go the cache group micro optimization route. You may be pleasantly surprised.

Having said that, you may try user-specific cache groups. The downside is lots of small caches that will be created. Those will likely require explicit removal on the background. For this you will bypass Cayenne cache API, and go directly to your provider. E.g. JCache CacheManager.destroyCache(..).

Andrus

> On Nov 8, 2017, at 10:00 PM, John Huss <[hidden email]> wrote:
>
> Yes, invalidating the cache group will remove the cached data for all users
> or query parameters, etc. It's not great.  You can make the cache group
> more specific (like by adding a username or something to it) and that will
> work, but you'll need to have these cache names configured in your cache
> provider already or have a default that makes sense.  That might be
> difficult to do.
>
> I'm interested to hear how others handle this.  I see this being a fairly
> big limitation of the query cache.
>
> On Wed, Nov 8, 2017 at 11:23 AM Lon Varscsak <[hidden email]> wrote:
>
>> Yeah, I’m not syncing between contexts (as much as I’d like to :P)…this is
>> about query caches.
>>
>> On Wed, Nov 8, 2017 at 3:56 AM, Musall, Maik <[hidden email]> wrote:
>>
>>> Hi Lon,
>>>
>>> have you read this? https://cayenne.apache.org/docs/4.0/cayenne-guide/
>>> performance-tuning.html#turning-off-synchronization-of-objectcontexts <
>>>
>> https://cayenne.apache.org/docs/4.0/cayenne-guide/performance-tuning.html#
>>> turning-off-synchronization-of-objectcontexts>
>>>
>>> I added this module to my server runtime builder (stripped down to the
>>> relevant bit for this discussion):
>>>
>>> Module cachePropertiesModule = new Module() {
>>>        @Override
>>>        public void configure( Binder binder ) {
>>>                MapBuilder<String> props = binder.bindMap( String.class,
>>> Constants.PROPERTIES_MAP );
>>>                props.put( Constants.SERVER_CONTEXTS_SYNC_PROPERTY,
>>> "false" );
>>>        }
>>> };
>>>
>>> Maik
>>>
>>>
>>>> Am 08.11.2017 um 01:40 schrieb Lon Varscsak <[hidden email]>:
>>>>
>>>> Hey all,
>>>>
>>>> I’ve been using cache groups to do refreshing of object lists and it
>>>> occurred to me today that this refresh is across all object contexts in
>>> my
>>>> application.  So if User A has a list of orders for their account and
>>> that
>>>> is cached with the group “orderHistory” and User B also has a list of
>>>> orders in “orderHistory”, running a refresh query will result in ALL
>>> users
>>>> refreshing their orderHistory caches.
>>>>
>>>> I’m not sure that this is what I want.  How have you solved this
>>>> situation?  Do you care? :P  I was thinking about doing something like
>>>> WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware of.
>>>>
>>>> Any feedback is appreciated.
>>>>
>>>> -Lon
>>>
>>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: Cache Groups

Andrus Adamchik
Ok, I can actually imagine when the efficiency of cooperating cache may become low. This would happen when the queries that have session-specific parameters in them (like user ID) make up the majority of all queries. We may actually brainstorm a generic solution for this in Cayenne. E.g. per-ObjectContext caches and cache group refreshing.

Andrus


> On Nov 9, 2017, at 10:45 AM, Andrus Adamchik <[hidden email]> wrote:
>
> "Cooperating" cache with shared cache groups decreases *average* DB load and improves performance on *average*. The assumption is that the app can afford to execute each individual DB query in isolation, and is mostly concerned with overall load. If you have multiple queries within the same request, some may need a refresh, some others may still be cached, with the overall performance still being acceptable. If the individual queries are too slow, you'd often be able to improve things with DB indexes.
>
> So I strongly recommend trying the above approach in a real app before you go the cache group micro optimization route. You may be pleasantly surprised.
>
> Having said that, you may try user-specific cache groups. The downside is lots of small caches that will be created. Those will likely require explicit removal on the background. For this you will bypass Cayenne cache API, and go directly to your provider. E.g. JCache CacheManager.destroyCache(..).
>
> Andrus
>
>> On Nov 8, 2017, at 10:00 PM, John Huss <[hidden email]> wrote:
>>
>> Yes, invalidating the cache group will remove the cached data for all users
>> or query parameters, etc. It's not great.  You can make the cache group
>> more specific (like by adding a username or something to it) and that will
>> work, but you'll need to have these cache names configured in your cache
>> provider already or have a default that makes sense.  That might be
>> difficult to do.
>>
>> I'm interested to hear how others handle this.  I see this being a fairly
>> big limitation of the query cache.
>>
>> On Wed, Nov 8, 2017 at 11:23 AM Lon Varscsak <[hidden email]> wrote:
>>
>>> Yeah, I’m not syncing between contexts (as much as I’d like to :P)…this is
>>> about query caches.
>>>
>>> On Wed, Nov 8, 2017 at 3:56 AM, Musall, Maik <[hidden email]> wrote:
>>>
>>>> Hi Lon,
>>>>
>>>> have you read this? https://cayenne.apache.org/docs/4.0/cayenne-guide/
>>>> performance-tuning.html#turning-off-synchronization-of-objectcontexts <
>>>>
>>> https://cayenne.apache.org/docs/4.0/cayenne-guide/performance-tuning.html#
>>>> turning-off-synchronization-of-objectcontexts>
>>>>
>>>> I added this module to my server runtime builder (stripped down to the
>>>> relevant bit for this discussion):
>>>>
>>>> Module cachePropertiesModule = new Module() {
>>>>       @Override
>>>>       public void configure( Binder binder ) {
>>>>               MapBuilder<String> props = binder.bindMap( String.class,
>>>> Constants.PROPERTIES_MAP );
>>>>               props.put( Constants.SERVER_CONTEXTS_SYNC_PROPERTY,
>>>> "false" );
>>>>       }
>>>> };
>>>>
>>>> Maik
>>>>
>>>>
>>>>> Am 08.11.2017 um 01:40 schrieb Lon Varscsak <[hidden email]>:
>>>>>
>>>>> Hey all,
>>>>>
>>>>> I’ve been using cache groups to do refreshing of object lists and it
>>>>> occurred to me today that this refresh is across all object contexts in
>>>> my
>>>>> application.  So if User A has a list of orders for their account and
>>>> that
>>>>> is cached with the group “orderHistory” and User B also has a list of
>>>>> orders in “orderHistory”, running a refresh query will result in ALL
>>>> users
>>>>> refreshing their orderHistory caches.
>>>>>
>>>>> I’m not sure that this is what I want.  How have you solved this
>>>>> situation?  Do you care? :P  I was thinking about doing something like
>>>>> WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware of.
>>>>>
>>>>> Any feedback is appreciated.
>>>>>
>>>>> -Lon
>>>>
>>>>
>>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Cache Groups

Lon Varscsak
Yeah, this is basically my scenario.  It's not "user specific", but the set
of data that each user is looking it is almost always different from other
users.  So if I have 50 users with list of order histories from 50
different customers and I want to refresh 1, the RefreshQuery will dump and
potentially reload a lot of data.

In an average eCommerce application, I'd agree it would probably not matter.

-Lon

On Thu, Nov 9, 2017 at 12:56 AM, Andrus Adamchik <[hidden email]>
wrote:

> Ok, I can actually imagine when the efficiency of cooperating cache may
> become low. This would happen when the queries that have session-specific
> parameters in them (like user ID) make up the majority of all queries. We
> may actually brainstorm a generic solution for this in Cayenne. E.g.
> per-ObjectContext caches and cache group refreshing.
>
> Andrus
>
>
> > On Nov 9, 2017, at 10:45 AM, Andrus Adamchik <[hidden email]>
> wrote:
> >
> > "Cooperating" cache with shared cache groups decreases *average* DB load
> and improves performance on *average*. The assumption is that the app can
> afford to execute each individual DB query in isolation, and is mostly
> concerned with overall load. If you have multiple queries within the same
> request, some may need a refresh, some others may still be cached, with the
> overall performance still being acceptable. If the individual queries are
> too slow, you'd often be able to improve things with DB indexes.
> >
> > So I strongly recommend trying the above approach in a real app before
> you go the cache group micro optimization route. You may be pleasantly
> surprised.
> >
> > Having said that, you may try user-specific cache groups. The downside
> is lots of small caches that will be created. Those will likely require
> explicit removal on the background. For this you will bypass Cayenne cache
> API, and go directly to your provider. E.g. JCache
> CacheManager.destroyCache(..).
> >
> > Andrus
> >
> >> On Nov 8, 2017, at 10:00 PM, John Huss <[hidden email]> wrote:
> >>
> >> Yes, invalidating the cache group will remove the cached data for all
> users
> >> or query parameters, etc. It's not great.  You can make the cache group
> >> more specific (like by adding a username or something to it) and that
> will
> >> work, but you'll need to have these cache names configured in your cache
> >> provider already or have a default that makes sense.  That might be
> >> difficult to do.
> >>
> >> I'm interested to hear how others handle this.  I see this being a
> fairly
> >> big limitation of the query cache.
> >>
> >> On Wed, Nov 8, 2017 at 11:23 AM Lon Varscsak <[hidden email]>
> wrote:
> >>
> >>> Yeah, I’m not syncing between contexts (as much as I’d like to
> :P)…this is
> >>> about query caches.
> >>>
> >>> On Wed, Nov 8, 2017 at 3:56 AM, Musall, Maik <[hidden email]>
> wrote:
> >>>
> >>>> Hi Lon,
> >>>>
> >>>> have you read this? https://cayenne.apache.org/
> docs/4.0/cayenne-guide/
> >>>> performance-tuning.html#turning-off-synchronization-of-objectcontexts
> <
> >>>>
> >>> https://cayenne.apache.org/docs/4.0/cayenne-guide/
> performance-tuning.html#
> >>>> turning-off-synchronization-of-objectcontexts>
> >>>>
> >>>> I added this module to my server runtime builder (stripped down to the
> >>>> relevant bit for this discussion):
> >>>>
> >>>> Module cachePropertiesModule = new Module() {
> >>>>       @Override
> >>>>       public void configure( Binder binder ) {
> >>>>               MapBuilder<String> props = binder.bindMap( String.class,
> >>>> Constants.PROPERTIES_MAP );
> >>>>               props.put( Constants.SERVER_CONTEXTS_SYNC_PROPERTY,
> >>>> "false" );
> >>>>       }
> >>>> };
> >>>>
> >>>> Maik
> >>>>
> >>>>
> >>>>> Am 08.11.2017 um 01:40 schrieb Lon Varscsak <[hidden email]
> >:
> >>>>>
> >>>>> Hey all,
> >>>>>
> >>>>> I’ve been using cache groups to do refreshing of object lists and it
> >>>>> occurred to me today that this refresh is across all object contexts
> in
> >>>> my
> >>>>> application.  So if User A has a list of orders for their account and
> >>>> that
> >>>>> is cached with the group “orderHistory” and User B also has a list of
> >>>>> orders in “orderHistory”, running a refresh query will result in ALL
> >>>> users
> >>>>> refreshing their orderHistory caches.
> >>>>>
> >>>>> I’m not sure that this is what I want.  How have you solved this
> >>>>> situation?  Do you care? :P  I was thinking about doing something
> like
> >>>>> WEB_SESSION_ID+cacheGroup…maybe this has some downsides I’m unaware
> of.
> >>>>>
> >>>>> Any feedback is appreciated.
> >>>>>
> >>>>> -Lon
> >>>>
> >>>>
> >>>
> >
>
>