【问题标题】:Ehcache cache size at runtime运行时的 Ehcache 缓存大小
【发布时间】:2018-03-16 00:27:39
【问题描述】:

我正在生产中运行一个大型 VM,并且想了解更多关于我在运行时的缓存大小的信息。我的缓存都是基于ehache

在运行时查看单个缓存大小的最佳方法是什么。使用 JMX 或 API

是否有任何选项可以通过对 CacheManager 的普通旧 java 调用进行配置,或者(暂时忽略 JMX)必须在一个大字符串中构建 XML 配置吗?

【问题讨论】:

    标签: java ehcache


    【解决方案1】:

    是的,使用 Ehcache,您可以配置缓存并仅通过 Java 代码检索其大小(无需 XML 配置)。集成一切的确切方式取决于您的特定架构;我将假设 Jersey 负责 API 的工作,Guice 负责依赖注入。

    定义缓存

    通过依赖注入使您的缓存管理器可用。这可以通过 Guice 模块完成:

    @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;
    }
    

    请注意,mycache 的统计信息已开启。

    同样,使用缓存可以完全在 Java 代码中完成,但这取决于您的架构和设计。通常我使用方法拦截(通过 AOP)来做到这一点,但这是另一个主题。

    通过 REST API 获取缓存统计信息

    鉴于您的 CacheManager 可通过依赖注入获得,您可以将其连接到 REST 端点并允许访问缓存统计信息:

    @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();
      }
    }
    

    现在您可以通过 REST 调用获取有关缓存的信息:

    GET /stats
    
    HTTP/1.1 200 OK
    Content-Type: text/plain; charset=utf-8
    
    mycache: 8 objects, 59 hits, 12 misses
    

    JMX 呢?

    Ehcache 使您可以轻松地将缓存管理器注册到 MBean 服务器。它可以用Java代码完成。更新您的 Guice 模块,将您的 cacheManager 注册到系统 MBeanServer

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

    现在您可以将 JConsole 附加到您的 Java 进程并在 MBean net.sf.ehcache.CacheStatistics 中找到您的缓存统计信息。

    【讨论】:

    • 如何获取缓存的堆使用情况?从上面的例子来看——这 8 个对象在堆上占用了多少字节?我们有多个 ehcache 实例,我正在寻找一种解决方案来提供缓存的堆使用。
    • 似乎 ehcache 从 2.6 版开始提供了一种使用 maxBytesOnLocalHeap() 配置缓存的方法。计算堆使用量会很方便 - ehcache.org/documentation/2.6/configuration/…
    • Ehcache 似乎不再提供 getObjectCount()。有其他选择吗?
    • @markthegrea 如果 getObjectCount() 正在返回缓存中的项目数,那么目前我们有另一种方法可以通过 getStatistics().getLocalHeapSize() 获得相同的数据,这将返回项目计数内存,还有 getLocalDiskSize() 也可以获取磁盘上的计数。
    【解决方案2】:

    在 EhCache 3 中(至少在我使用的 3.5 版本中)您可以通过缓存统计信息访问缓存大小。

    首先,您需要在缓存管理器上注册统计服务:

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

    然后,您可以检索缓存上的统计信息,它包含按层划分的大小(在 EhCache 3 中,您具有三个不同的层:堆、磁盘和堆外)

    CacheStatistics ehCacheStat = statisticsService.getCacheStatistics("myCache");
    ehCacheStat.getTierStatistics().get("OnHeap").getMappings();//nb element in heap tier
    ehCacheStat.getTierStatistics().get("OnHeap").getOccupiedByteSize()//size of the tier
    

    【讨论】:

    • 第二个代码块中的statisticsService 是从哪里得到的?我尝试将它暴露为 bean 并使用 Spring 自动装配它,但它说它找不到缓存。
    • @Niby 这两个块是相关的,我在第一个块中创建它,然后在第二个块中使用它。您可以将其保存在您的类或其他任何属性中...
    【解决方案3】:

    JMX 绝对是一个可行的解决方案。 EhCache 文档有一个专门用于此的page

    Here's an example 通过 JMX 配置 EhCache。链接的文章包含一个 Spring 配置,但如果您不使用 Spring,它很容易转换为原生 Java。

    【讨论】:

      猜你喜欢
      • 2014-09-29
      • 2017-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-07-05
      • 2020-02-29
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      相关资源
      最近更新 更多