kaz 02/02/18 18:08:28
Modified: xdocs UsingJCSBasicWeb.xml
Log:
More formatting (James beat me to the punch).
We should check to see if Aaron is ready to put a link in project.xml as
well so people can actually read this great doc. Aaron thoughts?
Revision Changes Path
1.3 +266 -237 jakarta-turbine-stratum/xdocs/UsingJCSBasicWeb.xml
Index: UsingJCSBasicWeb.xml
===================================================================
RCS file: /home/cvs/jakarta-turbine-stratum/xdocs/UsingJCSBasicWeb.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- UsingJCSBasicWeb.xml 19 Feb 2002 01:32:21 -0000 1.2
+++ UsingJCSBasicWeb.xml 19 Feb 2002 02:08:28 -0000 1.3
@@ -9,73 +9,86 @@
<body>
<section name="Using JCS: Some basics for the web">
<p>
-The primary bottleneck in most dynamic web-based application is the retrieval of
data from
-the database. While it is relatively inexpensive to add more front end servers to
scale the
-serving of pages and images and the processing of content, it is an expensive and
complex
-ordeal to scale the database. By taking advantage of data caching, most web
applications can
-reduce latency times and scale farther with fewer machines.
-
-JCS is a front tier cache that can be configured to maintain consistency across
multiple
-servers by using a centralized remote server or by lateral distribution of cache
updates.
-Other caches, like the Javlin EJB data cache, are basically in memory databases
that sit
-between your EJB's and your database. Rather than trying to speed up your slow
EJB's, you
-can avoid most of the network traffic and the complexity by implementing JCS front
tier
-caching. Centralize your EJB access or you JDBC data acces into local managers and
-perform the caching there.
- </p>
+ The primary bottleneck in most dynamic web-based application is
+ the retrieval of data from the database. While it is relatively
+ inexpensive to add more front end servers to scale the serving
+ of pages and images and the processing of content, it is an
+ expensive and complex ordeal to scale the database. By taking
+ advantage of data caching, most web applications can reduce
+ latency times and scale farther with fewer machines.
+ </p>
+ <p>
+ JCS is a front tier cache that can be configured to maintain
+ consistency across multiple servers by using a centralized
+ remote server or by lateral distribution of cache updates.
+ Other caches, like the Javlin EJB data cache, are basically in
+ memory databases that sit between your EJB's and your database.
+ Rather than trying to speed up your slow EJB's, you can avoid
+ most of the network traffic and the complexity by implementing
+ JCS front tier caching. Centralize your EJB access or you JDBC
+ data access into local managers and perform the caching there.
+ </p>
<subsection name="What to cache?">
<p>
-The data used by most web applications varies in its dynamicity, from completely
static to
-always changing at every request. Everything that has some degree of stability can
be
-cached. Prime candidates for caching range from the list data for stable
dropdowns, user
-information, discrete and infrequently changing information, to stable search
results that
-could be sorted in memory.
-
-Since JCS is distributed and allows updates and invalidations to be broadcast to
multiple
-listeners, frequently changing items can be easily cached and kept in synch through
your data
-access layer. For data that must be 100% up to date, say an account balance prior
to a
-transfer, the data should directly be retrieved from the database. If your
application allows
-for the viewing and editing of data, the data for the view pages could be cached,
but the edit
-pages should, in most cases, pull the data directly from the database.
- </p>
-
+ The data used by most web applications varies in its
+ dynamicity, from completely static to always changing at every
+ request. Everything that has some degree of stability can be
+ cached. Prime candidates for caching range from the list data
+ for stable dropdowns, user information, discrete and
+ infrequently changing information, to stable search results
+ that could be sorted in memory.
+ </p>
+ <p>
+ Since JCS is distributed and allows updates and invalidations
+ to be broadcast to multiple listeners, frequently changing
+ items can be easily cached and kept in sync through your data
+ access layer. For data that must be 100% up to date, say an
+ account balance prior to a transfer, the data should directly
+ be retrieved from the database. If your application allows
+ for the viewing and editing of data, the data for the view
+ pages could be cached, but the edit pages should, in most
+ cases, pull the data directly from the database.
+ </p>
</subsection>
-
<subsection name="How to cache discrete data">
- <p>
-Let's say that you have an e-commerce book store. Each book has a related set of
-information that you must present to the user. Let's say that 70% of your hits
during a
-particular day are for the same 1,000 popular items that you advertise on key pages
of your
-site, but users are still actively browsing your catalog of over a million books.
You cannot
-possibly cache your entire database, but you could dramatically decrease the load
on your
-database by caching the 1,000 or so most popular items.
- </p>
- <p>
-For the sake of simplicity let's ignore tie-ins and user-profile based suggestions
(also good
-candidates for caching) and focus on the core of the book detail page.
- </p>
- <p>
-A simple way to cache the core book information would be to create a value object
for book
-data that contains the necessary information to build the display page. This value
object
-could hold data from multiple related tables or book subtype table, but lets day
that you have
-a simple table called BOOK that looks something like this:
- </p>
-
+ <p>
+ Let's say that you have an e-commerce book store. Each book
+ has a related set of information that you must present to the
+ user. Let's say that 70% of your hits during a particular day
+ are for the same 1,000 popular items that you advertise on key
+ pages of your site, but users are still actively browsing your
+ catalog of over a million books. You cannot possibly cache
+ your entire database, but you could dramatically decrease the
+ load on your database by caching the 1,000 or so most popular
+ items.
+ </p>
+ <p>
+ For the sake of simplicity let's ignore tie-ins and
+ user-profile based suggestions (also good candidates for
+ caching) and focus on the core of the book detail page.
+ </p>
+ <p>
+ A simple way to cache the core book information would be to
+ create a value object for book data that contains the
+ necessary information to build the display page. This value
+ object could hold data from multiple related tables or book
+ subtype table, but lets day that you have a simple table
+ called BOOK that looks something like this:
+ </p>
<source><![CDATA[
-Table BOOK
-BOOK_ID_PK
-TITLE
-AUTHOR
-ISBN
-PRICE
-PUBLISH_DATE.
+ Table BOOK
+ BOOK_ID_PK
+ TITLE
+ AUTHOR
+ ISBN
+ PRICE
+ PUBLISH_DATE
]]></source>
-
- <p>
-We could create a value object for this table called BookVObj that has variable
with the
-same names as the table columns that might look like this:
- </p>
-
+ <p>
+ We could create a value object for this table called BookVObj
+ that has variable with the same names as the table columns
+ that might look like this:
+ </p>
<source><![CDATA[
package com.genericbookstore.data;
@@ -91,19 +104,20 @@
public String price;
public Date publishDate;
- public BookVObj() { }
+ public BookVObj()
+ {
+ }
}
]]></source>
-
- <p>
-Then we can create a manager called BookVObjManager to store and retrieve
BokVObj's.
-All access to core book data should go through this class, including inserts and
updates, to
-keep the caching simple. Let's make BookVObjManager a singleton that gets a JCS
access
-object in initialization. The start of the class might look like:
- </p>
-
+ <p>
+ Then we can create a manager called BookVObjManager to store
+ and retrieve BokVObj's. All access to core book data should
+ go through this class, including inserts and updates, to keep
+ the caching simple. Let's make BookVObjManager a singleton
+ that gets a JCS access object in initialization. The start of
+ the class might look like:
+ </p>
<source><![CDATA[
-
package com.genericbookstore.data;
import org.apache.stratum.jcs.JCS;
@@ -120,14 +134,14 @@
{
try
{
- bookCache = JCS.getInstance( "bookCache" );
+ bookCache = JCS.getInstance("bookCache");
}
- catch ( Exception e )
+ catch (Exception e)
{
// Handle cache region initialization failure
}
- // Do other initialization that may be neccesary, such as getting
+ // Do other initialization that may be necessary, such as getting
// references to any data access classes we may need to populate
// value objects later
}
@@ -135,262 +149,277 @@
/**
* Singleton access point to the manager.
*/
- public static BookVObjManager getInstance ()
+ public static BookVObjManager getInstance()
{
- if ( instance == null )
+ if (instance == null)
{
- synchronized ( BookVObjManager.class )
+ synchronized (BookVObjManager.class)
{
- if ( instance == null )
+ if (instance == null)
{
instance = new BookVObjManager();
}
- }
+ }
}
-
- synchronized ( instance )
+
+ synchronized (instance)
{
instance.checkedOut++;
}
-
+
return instance;
}
+}
]]></source>
+ <p>
+ To get a BookVObj we will need some access methods in the
+ manager. We should be able to get a non-cached version if
+ necessary, say before allowing an administrator to edit the
+ book data. The methods might look like:
+ </p>
+ <source><![CDATA[
+/**
+ * Retrieves a BookVObj. Default to look in the cache.
+ */
+public BookVObj getBookVObj(int id)
+{
+ return getBookVObj(id, true);
+}
- <p>
-To get a BookVObj we will need some access methods in the manager. We should be
able
-to get a non-cached version if necessary, say before allowing an administrator to
edit the
-book data. The methods might look like:
- </p>
+/**
+ * Retrieves a BookVObj. Second argument decides whether to look
+ * in the cache. Returns a new value object if one can't be
+ * loaded from the database. Database cache synchronization is
+ * handled by removing cache elements upon modification.
+ */
+public BookVObj getBookVObj(int id, boolean fromCache)
+{
+ BookVObj vObj = null;
- <source><![CDATA[
- /**
- * Retrieves a BookVObj. Default to look in the cache.
- */
- public BookVObj getBookVObj( int id )
+ // First, if requested, attempt to load from cache
+
+ if (fromCache)
{
- return getBookVObj( id, true );
+ vObj = (BookVObj) bookCache.get("BookVObj" + id);
}
- /**
- * Retrieves a BookVObj. Second argument decides whether to look in the
- * cache. Returns a new value object if one can't be loaded from the
- * database. Database cache synchronization is handled by removing cache
- * elements upon modification.
- */
- public BookVObj getBookVObj( int id, boolean fromCache )
+ // Either fromCache was false or the object was not found, so
+ // call loadBookVObj to create it
+
+ if (vObj == null)
{
- BookVObj vObj = null;
+ vObj = loadvObj(id);
+ }
- // First, if requested, attempt to load from cache
-
- if ( fromCache )
- {
- vObj = (BookVObj) bookCache.get( "BookVObj" + id );
- }
+ return vObj;
+}
- // Either fromCache was false or the object was not found, so call
- // loadBookVObj to create it
-
- if ( vObj == null )
- {
- vObj = loadvObj( id );
- }
-
- return vObj;
- }
+/**
+ * Creates a BookVObj based on the id of the BOOK table. Data
+ * access could be direct JDBC, some or mapping tool, or an EJB.
+ */
+public BookVObj loadBookVObj(int id)
+{
+ BookVObj vObj = new BookVObj();
- /**
- * Creates a BookVObj based on the id of the BOOK table.
- * Data access could be direct JDBC, some or mapping tool, or an EJB.
- */
- public BookVObj loadBookVObj( int id )
+ vObj.bookID = id;
+
+ try
{
- BookVObj vObj = new BookVObj();
-
- vObj.bookID = id;
+ boolean found = false;
- try
+ // load the data and set the rest of the fields
+ // set found to true if it was found
+
+ found = true;
+
+ // cache the value object if found
+
+ if (found)
{
- boolean found = false;
-
- // load the data and set the rest of the fields
- // set found to true if it was found
-
- found = true;
-
- // cache the value object if found
-
- if ( found )
- {
- // could use the defaults like this
- // bookCache.put( "BookVObj" + id, vObj );
- // or specify special characteristics
+ // could use the defaults like this
+ // bookCache.put( "BookVObj" + id, vObj );
+ // or specify special characteristics
- // get the default attributes and copy them,
- // then make changes to specific values
+ // get the default attributes and copy them,
+ // then make changes to specific values
- IElementAttributes attr =
+ IElementAttributes attr =
bookCache.getElementAttributes().copy();
-
- attr.setIsEternal( false );
-
- // expire after an hour
-
- attr.setMaxLifeSeconds( 60 * 120 );
- // put to cache with custom attributes
+ attr.setIsEternal(false);
- bookCache.put( "BookVObj" + id, vObj, attr );
- }
-
- }
- catch ( Exception e )
- {
- // Handle failure putting object to cache
+ // expire after an hour
+
+ attr.setMaxLifeSeconds(60 * 120);
+
+ // put to cache with custom attributes
+
+ bookCache.put("BookVObj" + id, vObj, attr);
}
- return vObj;
+ }
+ catch (Exception e)
+ {
+ // Handle failure putting object to cache
}
- ]]></source>
- <p>
-We will also need a method to insert and update book data. To keep the caching in
one
-place, this should be the primary way core book data is created. The method might
look
-like:
- </p>
+ return vObj;
+}
+ ]]></source>
+ <p>
+ We will also need a method to insert and update book data. To
+ keep the caching in one place, this should be the primary way
+ core book data is created. The method might look like:
+ </p>
<source><![CDATA[
- /**
- * Stores BookVObj's in database. Clears old items and caches new.
- */
- public int storeBookVObj( BookVObj vObj )
+/**
+ * Stores BookVObj's in database. Clears old items and caches
+ * new.
+ */
+public int storeBookVObj(BookVObj vObj)
+{
+ try
{
- try
- {
- // since any cached data is no longer valid, we should
- // remove the item from the cache if it an update.
+ // since any cached data is no longer valid, we should
+ // remove the item from the cache if it an update.
- if ( vObj.bookID != 0 )
- {
- bookCache.remove( "BookVObj" + vObj.bookID );
- }
-
- // get the default attributes, copy, and modify
-
- IElementAttributes attr = bookCache.getElementAttributes().copy();
- attr.setIsEternal( false );
- attr.setMaxLifeSeconds( 60 * 120 );
-
- // put the new object in the cache
-
- bookCache.put( "BookVObj" + id, vObj, attr );
- }
- catch ( Exception e )
+ if (vObj.bookID != 0)
{
- // Handle failure removing object or putting object to cache.
- }
- }
+ bookCache.remove("BookVObj" + vObj.bookID);
+ }
+
+ // get the default attributes, copy, and modify
+
+ IElementAttributes attr =
+ bookCache.getElementAttributes().copy();
+ attr.setIsEternal(false);
+ attr.setMaxLifeSeconds(60 * 120);
+
+ // put the new object in the cache
+
+ bookCache.put("BookVObj" + id, vObj, attr);
+ }
+ catch (Exception e)
+ {
+ // Handle failure removing object or putting object to cache.
+ }
+}
]]></source>
<p>
-We now have the basic infrastructure for caching the book data. I added auto
expiration to
-the elements to be safe, so the rest of the work will be to configure the cache
region.
+ We now have the basic infrastructure for caching the book
+ data. I added auto expiration to the elements to be safe, so
+ the rest of the work will be to configure the cache region.
</p>
</subsection>
<subsection name="Selecting the appropriate auxiliary caches">
<p>
-The first step in creating a cache region is to determine the makeup of the memory
cache.
-For the book store example, I would create a region that could store a bit over the
minimum
-number I want to have in memory, so the core items always readily available. I
would set the
-maximum memory size to 1200.
+ The first step in creating a cache region is to determine the
+ makeup of the memory cache. For the book store example, I
+ would create a region that could store a bit over the minimum
+ number I want to have in memory, so the core items always
+ readily available. I would set the maximum memory size to
+ 1200.
</p>
<p>
-For most cache regions you will want to use a disk cache if the data takes over
about .5
-milliseconds to create. The indexed disk cache is the most efficient disk caching
auxiliary,
-and for normal usage it is recommended. See the documentation.
+ For most cache regions you will want to use a disk cache if
+ the data takes over about .5 milliseconds to create. The
+ indexed disk cache is the most efficient disk caching
+ auxiliary, and for normal usage it is recommended. See the
+ documentation.
</p>
<p>
-The next step will be to select an appropriate distribution layer. If you have a
backend
-server running an apserver or scripts or are running multiple webserver vms on one
-machine, you might want to use the centralized remote cache. See documentation.
The
-lateral cache would be fine, but since the lateral cache binds to a port, you'd
have to
-configure each vm's lateral cache to listen to a different port on that machine.
+ The next step will be to select an appropriate distribution
+ layer. If you have a backend server running an apserver or
+ scripts or are running multiple webserver vms on one machine,
+ you might want to use the centralized remote cache. See
+ documentation. The lateral cache would be fine, but since the
+ lateral cache binds to a port, you'd have to configure each
+ vm's lateral cache to listen to a different port on that
+ machine.
</p>
<p>
-If your environment is very flat, say a few loadbalanced webservers and a database
machine
-or one webserver with multiple vm's and a database machine, then the lateral cache
will
-probably make more sense. The TCP lateral cache is recommended. See the
documentation.
+ If your environment is very flat, say a few load-balanced
+ webservers and a database machine or one webserver with
+ multiple vm's and a database machine, then the lateral cache
+ will probably make more sense. The TCP lateral cache is
+ recommended. See the documentation.
</p>
<p>
-For the book store configuration I will set up a region for the bookCache that uses
the LRU
-memory cache, the indexed disk auxiliary cache, and the remote cache. The
configuration
-file might look like this:
+ For the book store configuration I will set up a region for
+ the bookCache that uses the LRU memory cache, the indexed disk
+ auxiliary cache, and the remote cache. The configuration file
+ might look like this:
</p>
-
<source><![CDATA[
# DEFAULT CACHE REGION
# sets the default aux value for any non configured caches
jcs.default=DC,RFailover
jcs.default.cacheattributes=
- org.apache.stratum.jcs.engine.CompositeCacheAttributes
+org.apache.stratum.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=
- org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache
+org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache
# SYSTEM CACHE
# should be defined for the storage of group attribute list
jcs.system.groupIdCache=DC,RFailover
jcs.system.groupIdCache.cacheattributes=
- org.apache.stratum.jcs.engine.CompositeCacheAttributes
+org.apache.stratum.jcs.engine.CompositeCacheAttributes
jcs.system.groupIdCache.cacheattributes.MaxObjects=10000
jcs.system.groupIdCache.cacheattributes.MemoryCacheName=
- org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache
-
+org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache
+
# CACHE REGIONS AVAILABLE
-# Regions preconfirgured for caching
+# Regions preconfigured for caching
jcs.region.bookCache=DC,RFailover
jcs.region.bookCache.cacheattributes=
- org.apache.stratum.jcs.engine.CompositeCacheAttributes
+org.apache.stratum.jcs.engine.CompositeCacheAttributes
jcs.region.bookCache.cacheattributes.MaxObjects=1200
jcs.region.bookCache.cacheattributes.MemoryCacheName=
- org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache
+org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache
# AUXILIARY CACHES AVAILABLE
# Primary Disk Cache -- faster than the rest because of memory key storage
jcs.auxiliary.DC=
- org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
+org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DC.attributes=
- org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
+org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DC.attributes.DiskPath=/usr/opt/bookstore/raf
# Remote RMI Cache set up to failover
jcs.auxiliary.RFailover=
- org.apache.stratum.jcs.auxiliary.remote.RemoteCacheFactory
+org.apache.stratum.jcs.auxiliary.remote.RemoteCacheFactory
jcs.auxiliary.RFailover.attributes=
- org.apache.stratum.jcs.auxiliary.remote.RemoteCacheAttributes
+org.apache.stratum.jcs.auxiliary.remote.RemoteCacheAttributes
jcs.auxiliary.RFailover.attributes.RemoteTypeName=LOCAL
jcs.auxiliary.RFailover.attributes.FailoverServers=scriptserver:1102
jcs.auxiliary.RFailover.attributes.GetOnly=false
]]></source>
-
<p>
-I've set up the default cache settings in the above file to approximate the
bookCache settings.
-Other non-preconfigured cache regions will use the default settings. You only have
to configure
-the auxiliary caches once. For most caches you will not need to pre-configure our
regions unless
-the size of the elements varies radically. We could easliy put several hundred
thousand BookVObj's
-in memory. The 1200 limit was very conservative and would be more appropriate for
a large data
-structure.
- </p>
- <p>
-To get running with the book store example, I will also need to start up the remote
cache server
-on the scriptserver machine. The remote cache documentation describes the
configuration.
+ I've set up the default cache settings in the above file to
+ approximate the bookCache settings. Other non-preconfigured
+ cache regions will use the default settings. You only have to
+ configure the auxiliary caches once. For most caches you will
+ not need to pre-configure our regions unless the size of the
+ elements varies radically. We could easily put several
+ hundred thousand BookVObj's in memory. The 1200 limit was
+ very conservative and would be more appropriate for a large
+ data structure.
+ </p>
+ <p>
+ To get running with the book store example, I will also need
+ to start up the remote cache server on the scriptserver
+ machine. The remote cache documentation describes the
+ configuration.
</p>
<p>
-I now have a basic caching system implemented for my book data. Performance should
-improve immediately.
+ I now have a basic caching system implemented for my book
+ data. Performance should improve immediately.
</p>
</subsection>
</section>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>