Apache Ignite 缓存驱逐仍在内存中

问题描述 投票:0回答:2

在我们的 apache ignite 集群的稳定性测试中,我们遇到了一个与内存相关的问题,其中已用内存堆空间增加到 100%,并且没有像我们预期的那样下降。这就是我们所做的:

创建了一个带有FifoEvictionPolicy驱逐策略的缓存(最大值:10000,batchSize:100) 20 个并发线程在几个小时内一遍又一遍地执行以下场景: 将唯一条目添加到缓存中,然后获取该值以验证是否已添加。 此场景在测试期间创建了大约 230 万个条目。

我们的期望是由于我们的驱逐政策非常严格,最多 10000 个条目,内存应该稳定。然而,内存不断增加,直到达到最大堆大小。请参阅随附的内存图:

enter image description here

我们的问题是: 即使驱逐完成,为什么条目使用的内存仍然被分配?

需要添加的一件事是,我们执行了相同的测试,但在添加条目后删除了该条目。记忆现在稳定了:

enter image description here

更新测试用例和评论。

下面您将找到一个简单的junit测试来证明内存泄漏。 @a_gura 似乎是正确的 - 如果我们禁用 ExpiryPolicy ,事情就会按预期工作。但如果我们启用 ExpiryPolicy,堆似乎会在 ExpiryPolicy-duration 内被填满。测试用例:

public class IgniteTest {
  String cacheName = "my_cache";
  @Test
  public void test() throws InterruptedException {    
    IgniteConfiguration configuration = new IgniteConfiguration();
    Ignite ignite = Ignition.start(configuration);
    //create a large string to use as test value. 
    StringBuilder testValue = new StringBuilder();
    for (int i = 0; i < 10*1024; i ++) {
      testValue.append("a");
    }    
    CacheConfiguration cacheCfg = new CacheConfiguration();
    cacheCfg.setName(cacheName);
    cacheCfg.setEvictionPolicy(new FifoEvictionPolicy<>(10_000, 100));
    Duration duration = new Duration(TimeUnit.HOURS, 12);    
   cacheCfg.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(duration));
    cacheCfg.setCacheMode(CacheMode.LOCAL);
    cacheCfg.setBackups(0);
    Cache<Object, Object> cache = ignite.getOrCreateCache(cacheCfg);
    String lastKey = "";
    for (int i = 0; i < 10_000_101; i++){
      String key = "key#"+i;
      String value = testValue + "value#"+i;
      log.trace("storing {} {}", key, value);
      if (i % 1_000 == 0) {
        log.debug("storing {}", key);
      }
      cache.put(key, value);
      lastKey = key;
      Thread.sleep(1);
    }
    String verifyKey = "key#1";
    Assert.assertThat("first key should be evicted", cache.containsKey(verifyKey), CoreMatchers.is(false));    
    Assert.assertThat("last key should NOT be evicted", cache.containsKey(lastKey), CoreMatchers.is(true));    
    ignite.destroyCache(cacheName);    
  }
}
caching memory ignite
2个回答
1
投票

此问题已在 Ignite 1.8 中修复:https://issues.apache.org/jira/browse/IGNITE-3948

感谢提交错误的 @a_gura 和开发团队。


0
投票

FifoEvictionPolicy 在 ignite v2.16.0 中仍然无法工作。

我的代码如下:

    CacheConfiguration<Long, Person> cfg = new CacheConfiguration<Long, Person>("myCache");
    cfg.setEagerTtl(false);
    cfg.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 10)));
    cfg.setOnheapCacheEnabled(true);
    cfg.setEvictionPolicyFactory(() -> new FifoEvictionPolicy<Long, Person>(10));

// FifoEvictionPolicy evictionPlcy = new FifoEvictionPolicy<>(); // evictionPlcy.setMaxSize(20); // cfg.setEvictionPolicy(evictionPlcy);

    IgniteConfiguration igniteCfg = new IgniteConfiguration();
    igniteCfg.setCacheConfiguration(cfg);

    // Start a node.
    Ignite ignite = Ignition.start(igniteCfg);

    IgniteCache<Long, Person> personCache = ignite.getOrCreateCache(cfg);
    for(long i = 1; i < 30; i++) {
        Person person = new Person();
        person.id = i;
        person.salary = i;
        personCache.put(i, person);
    }
    
    Person p = personCache.get( 1L);
    if(p != null) {
      System.out.println("Key = " + p.id + ", Value = " + p.salary);
    }else {
        System.out.println("person is null");
    }

    IgniteBiPredicate<Long, Person> filter = new IgniteBiPredicate<Long, Person>() {
        @Override public boolean apply(Long key, Person p) {
            return key > 10 && key < 20;
        }
    };

    System.out.println("person query start -------");
    try (QueryCursor<Cache.Entry<Long, Person>> cursor = personCache.query(new ScanQuery<>(filter))) {
        for (Cache.Entry<Long, Person> entry : cursor)
            System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
    }
    System.out.println("person query end -------");

    Ignition.stop(ignite.name(), true);
© www.soinside.com 2019 - 2024. All rights reserved.