Tuesday, September 14, 2010

MapViewer performance tuning tips - part 4

In this post we will discuss best practices that deal with overall MapViewer deployment and configuration. We will also briefly touch base on how to monitor a running MapViewer instance to find troubling themes.

Deployment and Configuration

MapViewer is a J2EE application that runs in all modern J2EE containers. Deploying MapViewer is no different from deploying other J2EE applications.

Ideally MapViewer should be deployed to a dedicated JVM. In Oracle iAS world, this will be a dedicated OC4J instance, and in the WebLogic Server (WLS) world, this will be a dedicated server in a domain.

The reason is simple, MapViewer, while having a small foot print itself, often requires large amount of memory and CPU resources at run time depending on the work load. So it is best to deploy MapViewer to a JVM instance that runs only MapViewer (and minimum amount of other J2EE supporting services), so that unnecessary contentions or even interruptions with other applications can be minimized. It will also be easier to monitor MapViewer's performance when it is the only application running in the JVM.

Note however there is nothing inherently wrong to deploy and run MapViewer with other J2EE applications in a shared JVM.

JVM heap size

One of the key factors that will affect mapViewer performance is the amount of Heap memory allocated to the JVM. A minimum of 512 MB is recommended. On 32 bit operating systems, the maxium heap memory should not exceed 1.5GB (or 1500 MB). A typical MapViewer install will run happily with 1GB of heap memory.

You set heap memory via JVM's -Xmx option.

Another important memory allocation parameter is the young generation size within the JVM. Young generation is a pool of memory reserved for short-lived objects. A typical map request will result in MapViewer creating many such objects (for instance, to represent geographic features in memory), so a sufficiently large young generation within the heap is crucial in preventing the JVM spending too much time on garbage collection.

The young generation size can be set via the JVM parameter:

The first parameter specifies a starting young generation size of 80MB, while the second parameter indicates a maximum young generation size of 200M.

Typically the young generation size should not be more than 10 to 20 percent of the total heap size.

Spatial data cache
MapViewer lets you optionally configure an in-memory geometry data cache via the "spatial_data_cache" tag in mapViewerConfig.xml. This cache is used to buffer geometry features generated for themes whose caching mode is either set to ALL or NORMAL. (Note that you set a theme's caching mode in Map Builder's theme editor, in the Advanced tab).

When a theme's caching mode is set to ALL, MapViewer will load all of its features upon first request, and store the data in the cache. It also creates an in-memory R-Tree index on the features. All subsequent requests for this theme will be satisfied out of this cache, with no trips to the database.

When a theme's caching mode is set to NORMAL, MapViewer will store the theme's features as they are loaded. Note that MapViewer still queries the database every time such a theme is requested, but, in the event a feature is already in the cache, the un-marshaling or parsing of the database formatted geometry object is skipped, and the corresponding Java geometry object is reused out of the cache.

Our recommendation regarding theme caching, is to use caching mode ALL for small amount of themes that are based on small to medium sized tables (with couple hundred to tens of thousands of features) with static contents. And turn off NORMAL caching for all other themes. In other words, a pre-defined geometry theme should have its cache mode set to either NONE or (in rare cases) ALL.

The reason we do not recommend using the NORMAL caching mode is that it does not save much resource or time, in fact, it makes memory usage go up without much benefit at all. We could even argue that if too many theme features are cached the JVM may start doing more and more garbage collections which can adversely affect performance.

It is especially important to turn themes' caching off (by setting caching mode to NONE) before you start a tile pre-fetching task. During a tile prefetching, large amount of map requests will be sent to the MapViewer, and any cached geometries will soon become out dated, or rather, out of the region of interest.

Alternatively, prior to a large tile prefetching task, you can simply set the spatial data cache's max_cache_size to 0, which then automatically disables the caching of any theme's features.

We recommend the spatial_data_cache to have a max size of no more than 200MB (on a 32 bit OS), or 15 percent of total heap memory. In fact, we often found a performance boost by simply turning this cache off (setting its max size to zero)!

Note that when you have themes with caching mode ALL, mapViewer may not be able to fit all of its data in the cache, in which case it automatically switches the theme's cache mode to NORMAL (which as we mentioned earlier is not very ideal). So you need to carefully monitor any exception or error messages in the MapViewer log files to see if it failed to load all the data for themes with caching mode ALL. In the event this happens, you should simply set the theme's cache mode to NONE.

Note further that this internal memory cache will likely undergo major changes in MapViewer 11g R2 to truly boost performance.

Monitoring theme processing time
When you notice a slow map response time, the first thing you do is open the URL /mapviewer/admin.html, and check for slow themes.

This URL is only available in MapViewer version 11g R1 and later. It will require admin log in. Once logged in, you will see the Top Theme Queries text field, which you can submit to check which theme(s) are taking the most time to process. This can be very useful in quickly catching themes that are taking too long to return data from the database (indicating either a database performance issue, or a badly defined theme), or are returning too many rows/features, or both.

You can use the Reset Top Theme Queries form to wipe out existing top theme statistics, and MapViewer will automatically start collecting new stats for future map requests. This is useful if you have made changes to some themes and want to see if they are still the top (bad) themes.

You can also use the same URL to check the status of your MapViewer, such as how many active DB connections/sessions are being used currently.