Document & rendering caches
In a portal context, you can't afford make your users wait long seconds each time they apply any action. This is why this cache mechanism has been designed in the very early stages of the project. Typically, before generating a report the reportlet is checking if it has not already been generated in a former request, and if it is not yet expired.
- The rendering cache is the first reportlet cache level. A rendering cache entry is the final report output displayed in a reportlet window, and its dependencies (mainly the charts images). When this cache can be used, it allows ultra-fast report renders.
- The document cache is the second reportlet cache level, it is used only when no rendering entry is available for requests. Basically a document cache entry is a birt 'rptdocument', which is a kind of intermediate binary format used by Birt before rendering a report. Each time a Birt engine generates a 'rptdocument', it is compressed in memory by the reportlet and stored in the document cache.
Both rendering and document caches are managed with the leading caching solution Ehcache .
The orders of magnitude below are extracted from the visioneo live demo environmment, they may obviously vary depending on your context. In particular, the report generation time without any cache is completely subjective: it depends on your data sources, latency, report size & complexity, the design quality, etc.
If most of your reports last more than a certain time when none cache is used, you should probably change something in your architecture. Visioneo caches will greatly help you, but can't do anything on a first report generation! There are many ways to optimize Birt reports: add more filters/parameters, aggregate in sql queries rather in birt reports, using aggregated/de-normalized tables, stored procedures, more indexes, a columnar DBMS, etc.
|Caches||Report generation time||per minute/processor core|
|No cache used||from 1s to 5s||about 20 reports|
|Document cache||from 250ms to 1s||about 100 reports|
|Rendering cache||from 30ms to 60ms (*)||about 1000 reports|
(*) Time when the related cache entry is already in memory. If the entry is stored on the ehcache temporary disk space, the rendering values are slightly increased (generation time from 50ms to 100ms)
These caches can be fully customized in ehcache.xml file, which is located in the WEB-INF folder of your reportlet application. You may decide here if a cache is "eternal" or not, disk persistent or not, set an expiration time, the maximum memory that can be allocated, etc.
In this file, the most important thing to setup is the expiration time for visioneo.documents.cache and visioneo.rendering.cache. The default value is 14400 (4 hours). For instance If you need (nearly) real-time data, you could consider to set this expiration time to 600 (10 minutes). You should not set a value lower than 600.
It is of course possible to set different expiration time values for these 2 caches, you must follow this rule:
Expiration(document.cache) >= Expiration(rendering.cache) >= 600
Note the professional edition will allow to set up the cache expiration time directly in the reportlet preferences mode. As a consequence, you will be able to setup if necessary a different expiration time for each reportlet window.
Basically the document entries generated by the visioneo demo reports, once they are compressed, have an average size of 60 Kb. For the html rendering entries, it is about 20 Kb. Thus, for example if you decide in ehcache.xml to allow 1000 document entries and 1000 rendering entries in memory, it should consume about 1000*0,06+1000*0,02 = 80Mb in your JVM Heap memory.
In addition to html outputs, the rendering cache stores exported files as well (PDF, Excel, Word...). This is a great feature, however although exported documents are compressed in memory before being cached, it is significantly increasing the average rendering entry size.
Default reportlet values are 100 entries for documents and rendering entries, you should increase these values in your context. Make it with cautions, don't forget JVM memory heap size is constrainted by Garbage Collector duration.
When the maximum memory allowed is reached, the default ehcache.xml is setup to allow to write on a temporary disk space. Don't worry, even when ehcache needs to retrieve an entry from the disk, it is still very, very fast! However for a very large context, you could consider to use the fantastic Terracotta 'BigMemory' option. It is now possible to get a free license key from Terracotta, to manage in-memory caches upto 30Gb!
Note exported files with a size higher than 20 Mb (before compression) are not cached.
It is probably the most important thing to know about the document and the rendering caches: By default, cache entries are shared between all users . If 10 users request the same report, with exactly the same parameters values, they all use the same cache entry. This is obviously a major feature for your project scalability. If you wonder what happens if in addition all requests are simultaneous, this point is covered in the 'Parallelism' section below.
Some reports must be user specific, particularly for data security considerations. For example you may utilize the user id in your report main datasets. When a report is user-specific, we must warn the engine by adding a report parameter. Please refer to the article for more informations .
Parameters datasets (i.e. datasets used to produce a dynamic list in a combobox, for example) are not concerned by the cache mechanism.
Once again, to use this feature in a report we must declare hidden parameterst:
. This is of course facultative, and you should not add these parameters when they are not used in a report. Once declared in a report, the reportlet populates automatically the values, and they can be used in report scripts like any other report parameter:
Most of the time,
parameters are only used at render time: whatever the report size, the datasets and the report general layout won't change. Therefore it would be clunky to generate a new report each time the dimensions change.
For example, when a user is switching between a standard/maximized view, it would be a shame to wait long seconds just because the report is now maximized. A feature has been implemented for this kind of requirement: it is possible to specify that a parameter is only used at render time , by adding to the parameter(s) concerned a specific user property:
In the Eclipse Birt designer, the user properties can be set in the advanced properties dialog:
__heightparameters have this specific user property set to true, then whatever the reportlet window dimensions the same document cache entry is used. Therefore, if you render a chart report and then maximize it, the maximization will be very fast.
Another simple example: let's assume a user A includes in his private page a chart report with a size 800*600, and user B includes the same chart report with a size 500*350. With the
option, they share the same document cache entries!
As we have seen in this article, the reportlet engine is using several specific facultative parameters to decide when it should generate a new report, or get it from the cache:
- <your own security parameters>
A good practice is to create these parameters once and for all in a birt common library. You can even use the visioneo-commons library included for the demo reports, and drag&drop the parameters you need in your reports.
Visioneo reportlet takes advantage of the Terracotta 'blocking caches' to implement a fantastic parallelism management feature. if a report is run several times simultaneously, with exactly the same parameters, then the report threads involved are synchronized!
Only the first report request is generated, the next threads will directly get the result from the cache generated by the first thread. For example, if a user runs a large report, cancels it and runs it again, the second call will just wait for the first report has been generated, and then get it from the cache.
This feature is very powerful, and incredibly important for scalability considerations. Furthermore, if a pending report is "sleeping " more than 120 seconds, then the thread is stopped and an exception is thrown to free the reportlet window such:
Error when processing the export resource: report <report name> Lock timeout. Waited more than 120000ms to acquire lock for key.
- One of your report design has just been modified
- Your data have just undergone an exceptional batch ...
If your application server has the JMX services enabled, it is possible to control dynamically the caches through the java console (remove all entries, check some statistics, change the configuration, etc.):
If you can't enable the JMX services, it is possible to refresh the cache entries through the visioneo reportlet toolbar, when logged as an admin user.
11 February 2016
06 November 2015
28 October 2015
26 October 2015
08 October 2015
01 April 2015
01 April 2015
23 March 2015
23 March 2015
04 March 2015