Performance: sizing the Jackrabbit bundle cache properly
Our Digital Experience Manager (DX) product uses Apache Jackrabbit as the JCR implementation to store all of its content. Apache Jackrabbit is a powerful engine to store and manage content, and at its core it uses Persistence Managers to store and retrieve its data from different backends, i.e XML files or databases. A Jackrabbit persistence manager deals with one data structure - called a bundle - that is (de-)serialized from a backend, and usually represents the state of a JCR node. It may represent a workspace node or a versioned node. In the case of DX, nodes are serialized into a database table (using Java serialization).
The Jackrabbit Bundle Cache gathers - or caches - bundles that are comprised of a node with all its properties. If an item is not found in the bundle cache, it is read from the backend layer, i.e. database. By default, the bundle cache size is 8 MB if it is not specified; in DX, we have it set to 96MB as a part of the allocated JVM heap.
The downside is that the default cache size is not always appropriate for performance in every situation. In such cases, your app will need you to run a few tests to determine the right Jackrabbit bundle cache size. That means analyzing the miss to access ratio of the bundle cache which is shown in the jahia.log (or catalina.out) file like this:
2016-03-03 11:58:58,177: INFO [AbstractBundlePersistenceManager] - cachename=liveBundleCache[ConcurrentCache@3420d608], elements=19615, usedmemorykb=98298, maxmemorykb=98304, access=95165799, miss=67567717
You can see that this example demonstrates that the cache was pinged 95,165,799 times with a miss of 67,567,717. The miss tells us that the items were not found in cache therefore requiring a call to the persistence layer. Overall, it is ideal to have a lower miss to access ratio as an indicator of higher performance; this example shows a high miss to access ratio - 0.71 (71%). With a high ratio in this case, the cache size should be increased.
At the same time, you do not want to negatively impact the total performance of the app by assigning a huge amount of memory to bundle cache size. The best performance is usually achieved with a bundleCache size around 1/10th of JVM max heap size, with the caveat that this calculation could be different for assorted scenarios, i.e. in a heavy Read scenario you’ll want even less misses, so a higher bundleCache size.
Usually the versioning “bundleCacheSize” can be 2-4 times smaller than the default|live “bundleCacheSize” but it depends on the environment and usage - you can decide on your own by checking the “bundleCacheSize” lines in the console output.
If you chose to adjust the default settings, you can change the bundle cache size from “<dx-installation-dir>/webapps/ROOT/WEB-INF/etc/repository/jackrabbit/repository.xml” and “<dx-installation-dir>/digital-factory-data/repository/workspaces/(default|live)/workspace.xml” using tags like (with the value being defined in MBs):
<PersistenceManager class="@PERSISTENCE_CLASS@"> <param name="bundleCacheSize" value="256"/> </PersistenceManager>
On the first start of DX, the bundle cache size setting is retrieved from “<dx-installation-dir>/webapps/ROOT/WEB-INF/etc/repository/jackrabbit/repository.xml” and set into each workspace.xml. Any adjustments to bundle cache will have to be configured in the respective workspace XML file. However, the versioning “bundleCacheSize” is still managed in the “<dx-installation-dir>/webapps/ROOT/WEB-INF/etc/repository/jackrabbit/repository.xml” under the “Versioning” element. After the adjustments, DX will have to be restarted for these changes to take effect.
You can change bundle cache size values from “<digital-factory-config>/jahia/jahia.properties” file by providing the following entries:
The first entry sets the bundle cache size of the persistence manager for live and default workspaces to 128 MB. The second one – the size of the cache for versioning persistence manager.