Ehcache cache size at runtime
Asked Answered
D

3

9

I am running a large VM in production and would like to understand more about my cache size at runtime. My caches are all based upon ehache

What is the best way to see the size of individual caches at runtime. Either using JMX or API

Is there any option to configure by plain-old-java calls to the CacheManager, or (ignoring JMX for the moment) must one build the XML configuration slug up in a big string?

Defendant answered 5/11, 2012 at 10:17 Comment(0)
F
17

Yes, using Ehcache, you can configure your caches and retrieve their sizes by Java code only (no XML config). The exact way to integrate everything depends on your specific architecture; I'm going to assume Jersey for doing API stuff and Guice for dependency injection.

Defining your cache

Make your cache manager available via dependency injection. This can be done via a Guice module:

@Provides
@Singleton
CacheManager provideCacheManager() {
  CacheManager cacheManager = CacheManager.create();

  /* very basic cache configuration */
  CacheConfiguration config = new CacheConfiguration("mycache", 100)
    .timeToLiveSeconds(60)
    .timeToIdleSeconds(30)
    .statistics(true);

  Cache myCache = new Cache(config);
  cacheManager.addCacheIfAbsent(myCache);

  return cacheManager;
}

Notice that statistics is turned on for mycache.

Again, using your cache can be done entirely in Java code but depends on your architecture and design. Typically I do this using method interception (via AOP) but that's another topic.

Fetch cache stats via REST API

Given your CacheManager is available via dependency injection you can then wire it up to a REST endpoint and allow access to cache statistics:

@Path("stats")
@Produces("text/plain")
public class StatsResource {
  @Inject private CacheManager cacheManager;

  @GET
  public String stats() {
    StringBuffer sb = StringBuffer();

    /* get stats for all known caches */
    for (String name : cacheManager.getCacheNames()) {
      Cache cache = cacheManager.getCache(name);
      Statistics stats = cache.getStatistics();

      sb.append(String.format("%s: %s objects, %s hits, %s misses\n",
        name,
        stats.getObjectCount(),
        stats.getCacheHits(),
        stats.getCacheMisses()
      ));
    }
    return sb.toString();
  }
}

Now you can fetch information about your caches by REST call:

GET /stats

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8

mycache: 8 objects, 59 hits, 12 misses

What about JMX?

Ehcache makes it easy to register your cache manger with an MBean server. It can be done in Java code. Update your Guice module, registering your cacheManager to the system MBeanServer:

MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ManagementService.registerMBeans(cacheManager, mBeanServer, false, false, false, true);

Now you can attach JConsole to your Java process and find your cache statistics in the MBean net.sf.ehcache.CacheStatistics.

Frame answered 8/10, 2013 at 12:56 Comment(4)
How do I get the heap usage by the cache? From the above example - how many bytes do the 8 objects occupy on heap? We have multiple ehcache instances and I am looking for a solution that gives the heap usage of a cache.Joubert
It seems ehcache starting from version 2.6 provides a way to configure the cache with maxBytesOnLocalHeap(). Would be handy to calculate the heap usage - ehcache.org/documentation/2.6/configuration/…Joubert
It seems Ehcache no longer provides a getObjectCount(). Is there an alternative?Inhibitory
@Inhibitory if getObjectCount() was returning the number of items in the cache then currently we have an alternate way to get the same via getStatistics().getLocalHeapSize(), this will return the item count in memory, and there is getLocalDiskSize() also to get the count on disk.Celio
L
3

In EhCache 3 (at least in the 3.5 version that I uses) you can access cache size via the cache statistics.

First, you need to register the statistic service on your cache manager :

StatisticsService statisticsService = new DefaultStatisticsService();
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
        .using(statisticsService)
        .build();
cacheManager.init();

Then, you can retrieve the statistics on your cache and it contains size by tiers (in EhCache 3 you have three different tiers : heap, disk and offheap)

CacheStatistics ehCacheStat = statisticsService.getCacheStatistics("myCache");
ehCacheStat.getTierStatistics().get("OnHeap").getMappings();//nb element in heap tier
ehCacheStat.getTierStatistics().get("OnHeap").getOccupiedByteSize()//size of the tier
Levitation answered 15/3, 2018 at 16:27 Comment(3)
Where do you get statisticsService from in you're second code block? I tried exposing it as a bean and autowiring it with Spring, but then it says that it can not find the cache.Armil
@Armil the two blocks are related, I create it in the first block then use it in the second one. You can keep it in an attribute of your classes or anything else ...Levitation
Its returns -1, and idea why?Principally
N
0

JMX is definitely a viable solution. The EhCache doc has a page specifically for this.

Here's an example of configuring EhCache via JMX. The linked article contains a Spring config, but it's easily translatable to native Java if you're not using Spring.

Ninon answered 5/11, 2012 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.