1
<?xml version='1.0' encoding="UTF-8"?>
2
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
5
~ Copyright (c) 2008, Red Hat Middleware, LLC. All rights reserved.
7
~ This copyrighted material is made available to anyone wishing to use, modify,
8
~ copy, or redistribute it subject to the terms and conditions of the GNU
9
~ Lesser General Public License, v. 2.1. This program is distributed in the
10
~ hope that it will be useful, but WITHOUT A WARRANTY; without even the implied
11
~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
~ Lesser General Public License for more details. You should have received a
13
~ copy of the GNU Lesser General Public License, v.2.1 along with this
14
~ distribution; if not, write to the Free Software Foundation, Inc.,
15
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
~ Red Hat Author(s): Brian Stansberry
19
<chapter id="eviction">
21
<title>Cache Eviction</title>
23
<sect1 id="eviction-overview" revision="1">
24
<title>Overview</title>
27
<emphasis>Eviction</emphasis> refers to the process by which old,
28
relatively unused, or excessively voluminous data can be dropped
29
from the cache, allowing the cache to remain within a memory budget.
30
Generally, applications that use the Second Level Cache should
31
configure eviction, unless only a relatively small amount of
32
reference data is cached. This chapter provides a brief overview
33
of how JBoss Cache eviction works, and then explains how to configure
34
eviction to effectively manage the data stored in a Hibernate Second
35
Level Cache. A basic understanding of JBoss Cache eviction and of
36
concepts like FQNs is assumed; see the <emphasis>JBoss Cache User Guide</emphasis>
40
<sect2 id="eviction-overview-process" revision="1">
41
<title>The Eviction Process</title>
44
The JBoss Cache eviction process is fairly straightforward. Whenever
45
a node in a cache read or written to, added or removed, the cache
46
finds the <emphasis>eviction region</emphasis> (see below) that
47
contains the node and passes an <emphasis>eviction event</emphasis>
48
object to the <emphasis>eviction policy</emphasis> (see below)
49
associated with the region. The eviction policy uses the stream of
50
events it receives to track activity in the region. Periodically,
51
a background thread runs and contacts each region's eviction
52
policy. The policy uses its knowledge of the activity in the region,
53
along with any configuration it was provided at startup, to determine
54
which if any cache nodes should be evicted from memory. It then
55
tells the cache to evict those nodes. Evicting a node means
56
dropping it from the cache's in-memory state. The eviction only
57
occurs on that cache instance; there is no cluster-wide eviction.
61
An important point to understand is that eviction proceeds
62
independently on each peer in the cluster, with what gets
63
evicted depending on the activity on that peer. There is no
64
"global eviction" where JBoss Cache removes a piece of data in
65
every peer in the cluster in order to keep memory usage inside
66
a budget. The Hibernate/JBC integration layer may remove some
67
data globally, but that isn't done for the kind of memory
68
management reasons we're discussing in this chapter.
72
An effect of this is that even if a cache is configured for
73
replication, if eviction is enabled the contents of a cache will
74
be different between peers in the cluster; some may have evicted
75
some data, while others will have evicted different data. What
76
gets evicted is driven by what data is accessed by users on each
81
Controlling when data is evicted from the cache is a matter
82
of setting up appropriate eviction regions and configuring
83
appropriate eviction policies for each region.
88
<sect2 id="eviction-overview-regions" revision="1">
89
<title>Eviction Regions</title>
92
JBoss Cache stores its data in a set of nodes organized in a tree
93
structure. An eviction region is a just a portion of the tree
94
to which an eviction policy has been assigned. The name of the
95
region is the FQN of the topmost node in that portion of the tree.
96
An eviction configuration always needs to include a special region
97
named <literal>_default_</literal>; this region is rooted in the
98
root node of the tree and includes all nodes not covered by
102
It's possible to define regions that overlap. In other words, one
103
region can be defined for <emphasis>/a/b/c</emphasis>, and another
104
defined for <emphasis>/a/b/c/d</emphasis> (which is just the
105
<emphasis>d</emphasis> subtree of the <emphasis>/a/b/c</emphasis>
106
sub-tree). The algorithm that assigns eviction events to eviction
107
regions handles scenarios like this consistently by always choosing
108
the first region it encounters. So, if the algorithm needed to
109
decide how to handle an event affecting <emphasis>/a/b/c/d/e</emphasis>,
110
it would start from there and work its way up the tree until it
111
hits the first defined region - in this case <emphasis>/a/b/c/d</emphasis>.
115
<sect2 id="eviction-overview-policies" revision="1">
116
<title>Eviction Policies</title>
119
An <emphasis>Eviction Policy</emphasis> is a class that knows how
120
to handle eviction events to track the activity in its region.
121
It may have a specialized set of configuration properties that
122
give it rules for when a particular node in the region should be
123
evicted. It can then use that configuration and its knowledge of
124
activity in the region to to determine what nodes to evict.
128
JBoss Cache ships with a number of eviction policies. See the
129
<emphasis>JBoss Cache User Guide</emphasis> for a discussion of
130
all of them. Here we are going to focus on just two.
133
<sect3 id="eviction-overview-policies-lru" revision="1">
134
<title>The <literal>LRUPolicy</literal></title>
137
The <literal>org.jboss.cache.eviction.LRUPolicy</literal> evicts
138
nodes that have been Least Recently Used. It has the following
139
configuration parameters:
144
<literal>maxNodes</literal>
145
- This is the maximum number of nodes allowed in this region.
146
0 denotes no limit. If the region has more nodes than this,
147
the least recently used nodes will be evicted until the number
148
of nodes equals this limit.
152
<literal>timeToLiveSeconds</literal>
153
- The amount of time a node is not written to or read (in seconds)
154
before the node should be evicted. 0 denotes no limit. Nodes that
155
exceed this limit will be evicted whether or not a
156
<literal>maxNodes</literal> limit has been breached.
160
<literal>maxAgeSeconds</literal>
161
- Lifespan of a node (in seconds) regardless of idle time before
162
the node is swept away. 0 denotes no limit. Nodes that
163
exceed this limit will be evicted whether or not a
164
<literal>maxNodes</literal> or <literal>timeToLiveSeconds</literal>
165
limit has been breached.
169
<literal>minTimeToLiveSeconds</literal>
170
- the minimum amount of time a node must be allowed to live after
171
being accessed before it is allowed to be considered for eviction.
172
0 denotes that this feature is disabled, which is the default value.
173
Should be set to a value less than <literal>timeToLiveSeconds</literal>.
174
It is recommended that this be set to a value slightly greater
175
than the maximum amount of time a transaction that affects the
176
region should take to complete. Configuring this is particularly
177
important when optimistic locking is used in conjunction with
183
<sect3 id="eviction-overview-policies-null" revision="1">
184
<title>The <literal>NullEvictionPolicy</literal></title>
187
The <literal>org.jboss.cache.eviction.NullEvictionPolicy</literal>
188
is a simple policy that very efficiently does ... nothing. It
189
is used to efficiently short-circuit eviction handling for regions
190
where you don't want objects to be evicted (e.g. the timestamps
191
cache, which should <emphasis>never</emphasis> have data
192
evicted). Since the <literal>NullEvictionPolicy</literal> doesn't
193
actually evict anything, it doesn't take any configuration parameters.
201
<sect1 id="eviction-organization" revision="1">
202
<title>Organization of Data in the Cache</title>
205
In order to understand how to configure eviction, you need to
206
understand how Hibernate organizes data in the cache.
209
<sect2 id="eviction-organization-elements" revision="1">
210
<title>Region Prefix and Region Name</title>
213
All FQNs in a second level cache include two elements:
219
A <emphasis>Region Prefix</emphasis>, which is simply
220
any value assigned to the
221
<literal>hibernate.cache.region_prefix</literal> Hibernate
222
configuration property. If no Region Prefix is set, this
223
portion of the FQN is omitted.
226
If different session factories are sharing the same underlying
227
JBoss Cache instance(s) it is <emphasis>strongly encouraged</emphasis>
228
that a distinct Region Prefix be assigned to each. This will
229
help ensure that the different session factories cache their
230
data in different subtrees in JBoss Cache.
235
A <emphasis>Region Name</emphasis>, which is either
240
any value assigned to a <literal><cache></literal> element's
241
<literal>region</literal> attribute in a class or collection mapping.
242
See <xref linkend="eviction-organization-entity"/> for
248
Any value assigned to a Hibernate <literal>Query</literal>
249
object's <literal>cacheRegion</literal> property. See
250
<xref linkend="eviction-organization-query"/> for an
256
The <emphasis>escaped class name</emphasis> of the type
257
being cached. An <emphasis>escaped class name</emphasis>
258
is simply a fully-qualified class name with any
259
<literal>.</literal> replaced with a <literal>/</literal>
260
-- for example <literal>org/example/Foo</literal>.
270
<sect2 id="eviction-organization-entity" revision="1">
271
<title>Entities</title>
274
The FQN for the cache region where entities of a particular class
275
are stored is derived as follows:
278
<literal>/</literal> + <emphasis>Region Prefix</emphasis> + <literal>/</literal>
279
+ <emphasis>Region Name</emphasis> + <literal>/ENTITY</literal>
283
If no region prefix was specified, the leading <literal>/</literal> and
284
<emphasis>Region Prefix</emphasis> is not included in the FQN.
285
So, if <literal>hibernate.cache.region_prefix</literal> was set to
286
"appA" and a class was mapped like this:
289
<programlisting><![CDATA[<class name="org.example.Foo">
290
<cache usage="transactional" region="foo_region"/>
292
</class>]]></programlisting>
295
The FQN of the region where <literal>Foo</literal> entities
296
would be cached is <literal>/appA/foo_region/ENTITY</literal>.
300
If the class mapping does not include a <literal>region</literal>
301
attribute, the region name is based on the name of the entity
305
<programlisting><![CDATA[<class name="org.example.Bar">
306
<cache usage="transactional"/>
308
</class>]]></programlisting>
311
the FQN of the region where <literal>Bar</literal> entities
312
would be cached is <literal>/appA/org/example/Bar/ENTITY</literal>.
316
<sect2 id="eviction-organization-coll" revision="1">
317
<title>Collections</title>
320
The FQN for the cache region where entities of a particular class
321
is stored is derived as follows:
324
<literal>/</literal> + <emphasis>Region Prefix</emphasis> + <literal>/</literal>
325
+ <emphasis>Region Name</emphasis> + <literal>/COLL</literal>
329
So, let's say our example <literal>Foo</literal> entity
330
included a collection field <literal>bars</literal> that
334
<programlisting><![CDATA[<class name="org.example.Foo">
335
<cache usage="transactional"/>
338
<cache usage="transactional" region="foo_region"/>
339
<key column="FOO_ID"/>
340
<one-to-many class="org.example.Bar"/>
342
</class>]]></programlisting>
345
The FQN of the region where the collection would be cached
347
<literal>/appA/foo_region/COLL</literal>.
351
If the collection's <literal><cache></literal> element
352
did not include a <literal>region</literal>, the FQN would be
353
<literal>/appA/org/example/Foo/COLL</literal>.
357
<sect2 id="eviction-organization-query" revision="1">
358
<title>Queries</title>
361
Queries follow this pattern:
365
<literal>/</literal> + <emphasis>Region Prefix</emphasis> + <literal>/</literal>
366
+ <emphasis>Region Name</emphasis> + <literal>/QUERY</literal>
370
Say we had the following query (again with a region prefix set to
374
<programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog " +
375
"where blog.blogger = :blogger")
376
.setEntity("blogger", blogger)
379
.setCacheRegion("frontpages")
380
.list();]]></programlisting>
383
The FQN of the region where this query's results would be cached
384
would be <literal>/appA/frontpages/QUERY</literal>.
388
If the call to <literal>setCacheRegion("frontpages")</literal>
389
were ommitted, the <emphasis>Region Name</emphasis> portion of
390
the FQN would be based on a Hibernate class:
391
<literal>/appA/org/hibernate/cache/StandardQueryCache/QUERY</literal>
395
<sect2 id="eviction-organization-timestamps" revision="1">
396
<title>Timestamps</title>
399
Timestamps follow this pattern:
403
<literal>/TS/</literal> + <emphasis>Region Prefix</emphasis> +
404
<literal>/org/hibernate/cache/UpdateTimestampsCache</literal>
408
again with a <literal>/</literal> and the <emphasis>Region Prefix</emphasis>
409
portion omitted if no region prefix was set.
413
Note that in the timestamps case the special constant ("TS") comes
414
at the start of the FQN rather than the end. This makes it easier
415
to ensure that eviction is never enabled for the timestamps region.
420
<sect1 id="eviction-organization-example" revision="1">
421
<title>Example Configuration</title>
424
So far we've been looking at things in the abstract; let's see an
425
example of how this comes together. In this example, imagine we
426
have a Hibernate application with the following characteristics.
430
<para>Query caching is enabled.</para>
434
There is a region prefix set as part of the Hibernate
435
configuration: <literal>hibernate.cache.region_prefix==appA</literal>
440
Some cachable entities and collections have a region
441
name of "reference" set in their Hibernate mapping.
446
Some cachable queries have the "reference" region name
447
set when they are created.
452
Other cachable entities and collections in the
453
<literal>org.example.hibernate</literal> package don't have a
454
region name set in their Hibernate mapping.
459
Other cachable queries don't have a region name set when they
467
Let's see a possible eviction configuration for this scenario:
470
<programlisting><![CDATA[<attribute name="EvictionPolicyConfig">
473
<attribute name="wakeUpIntervalSeconds">5</attribute>
474
<attribute name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
477
Default region to pick up anything we miss in the more
478
specific regions below.
480
<region name="/_default_">
481
<attribute name="maxNodes">500</attribute>
482
<attribute name="timeToLiveSeconds">300</attribute>
483
<attribute name="minTimeToLiveSeconds">120</attribute>
486
<!-- Don't ever evict modification timestamps -->
488
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
490
<!-- Reference data -->
491
<region name="/appA/reference">
492
<!-- Keep all reference data if it's being used -->
493
<attribute name="maxNodes">0</attribute>
494
<!-- Keep it around a long time (4 hours) -->
495
<attribute name="timeToLiveSeconds">14400</attribute>
496
<attribute name="minTimeToLiveSeconds">120</attribute>
499
<!-- Be more aggressive about queries on reference data -->
500
<region name="/appA/reference/QUERY">
501
<attribute name="maxNodes">200</attribute>
502
<attribute name="timeToLiveSeconds">1000</attribute>
503
<attribute name="minTimeToLiveSeconds">120</attribute>
507
Lots of entity instances from this package, but different
508
users are unlikely to share them. So, we can cache
509
a lot, but evict unused ones pretty quickly.
511
<region name="/appA/org/example/hibernate">
512
<attribute name="maxNodes">50000</attribute>
513
<attribute name="timeToLiveSeconds">1200</attribute>
514
<attribute name="minTimeToLiveSeconds">120</attribute>
517
<!-- Clean up misc queries very promptly -->
518
<region name="/appA/org/hibernate/cache/StandardQueryCache">
519
<attribute name="maxNodes">200</attribute>
520
<attribute name="timeToLiveSeconds">240</attribute>
521
<attribute name="minTimeToLiveSeconds">120</attribute>
525
</attribute>]]></programlisting>
532
<para>The <literal>wakeUpIntervalSeconds</literal> configuration
533
controls how often the background eviction process kicks
538
<para>The first <literal>policyClass</literal> configuration
539
sets the default eviction policy class to use for each region.
540
Here we want to use the standard <literal>LRUPolicy</literal>
541
This can be overridden on a per-region basis, as is done
542
here for the <literal>/TS</literal> region.</para>
545
<para>We set up a <literal>/_default_</literal> region. Having
546
such a region is a requirement if eviction is used. Here we
547
don't expect any data to end up in this default region, but
548
if by mistake someone adds a new entity type that doesn't fall
549
into one of our other regions, we may not have a large memory
550
budget for it so we evict fairly agressively.
554
<para>Evicting timestamps is forbidden, so we add a
555
<literal>/TS</literal> region that disables it. Here we
556
see how to override the default eviction policy.</para>
560
The <literal>/appA/reference</literal> region covers our
561
reference data entities and collections. This is our most
562
likely to be reused data, so we configure the cache to be
563
very slow to evict it.
568
The queries related to our reference data are less likely to
569
be reused, and may take up a lot of memory, so we override the
570
<literal>/appA/reference</literal> region with a
571
<literal>/appA/reference/QUERY</literal> region that is more
572
agressive about eviction.
577
The <literal>org.example.hibernate</literal> package includes a
578
lot of entity classes like <literal>Order</literal>, where
579
there are hundreds of thousands of records in the database.
580
These are unlikely to be reused across users, but we have a lot
581
of users and want to be able to cache many of them so a user
582
can have fast access to his or her data during the
583
course of their interaction with the system. So we create a
584
<literal>/appA/org/example/hibernate</literal> region
585
with a high <literal>maxNodes</literal> value but a fairly
586
low <literal>timeToLiveSeconds</literal>. The low time-to-live
587
ensures an <literal>Order</literal> is evicted quickly once a
588
user is done with it.
592
<para>Finally, cacheable queries that aren't assigned to
593
to the <literal>reference</literal> region will end up in
594
<literal>/appA/org/hibernate/cache/StandardQueryCache</literal>.
595
We've elected not to keep these around long at all.
602
<sect1 id="eviction-organization-best" revision="1">
603
<title>Best Practices</title>
606
Some best practices to follow:
612
Set <literal>hibernate.cache.region_prefix</literal> in your
613
configuration. It makes it simple to ensure the different session
614
factories don't step on each other if they share a JBoss Cache
620
Always set up an eviction region for the <literal>/TS</literal>
621
FQN that uses the <literal>NullEvictionPolicy</literal>. This
622
will ensure that timestamps never get evicted. Even if you are
623
not doing query caching or aren't caching timestamps in a
624
particular cache, this is still a good practice, as it costs
625
almost nothing and helps to ensure that timestamp eviction doesn't
626
slip in unnoticed later.
631
Assign a region to your entities, collections and queries rather
632
than relying on class names to compose the FQN. It makes
633
it easier to set up eviction, and helps prevent your eviction
634
setup breaking if class names are refactored.
639
Assign a different region name to your entities, collections or
640
queries that have different desirable eviction characteristics.
641
Put objects like often used reference data in one region, data
642
probably only accessed by a single user in another. Aggressively
643
evict the latter region; be less agressive with the former if
649
In some cases, there is an external application (i.e. outside
650
of Hibernate's control) that can modify data in the database.
651
Generally, a Second Level Cache should not be used in this sort
652
of case, since it can result in data in the cache being out of
653
date with respect to the database. But sometimes application
654
designers can tolerate having out of date data in the cache. In
655
this sort of situation, use an <literal>LRUPolicy</literal> with
656
a fairly low <literal>maxAgeSeconds</literal>. This will ensure
657
that out-of-date data eventually gets flushed from the cache.
b'\\ No newline at end of file'