簡體   English   中英

使用Terracotta的EHCache如何處理從分布式堆中逐出?

[英]How does EHCache using Terracotta handle eviction from the distributed heap?

我們最近開始將EHCache與Terracotta結合使用,以為應用程序數據運行分布式數據緩存。 假設任何客戶節點的堆內存約為2gb,而服務器節點的內存約為8gb。 我們每天產生大量數據,大約1.5gb。

通常,任何一個客戶端都將使用特定日期的數據集(大約1.5gb),但是服務器顯然必須保留所有這些數據集。

當堆變大時,我希望失效的工作方式基於LRU。 因此,如果任何特定的L1客戶端緩存太大(例如,從day1切換到day2),我希望它會從L1的所有day1數據中退出。 如果L6在我們獲得第6個數據集時變得太大,那么最早的數據集將完全過期。 對於生存時間或空閑時間值,我真的沒有任何意見,因此我將其保留下來。

經過幾天的研究,我認為這沒有達到我的預期。 例如,我運行了一個L2 max元素為4的測試。我為其填充了四個元素。 然后我去提出第五個要素。 Cache.put()無異常返回,但是緊隨其后的具有相同鍵的Cache.get()返回null!

所以我的問題是,如何讓EHCache + Terracotta來做我想做的事情,或者至少要做些什么?

經過一番混亂之后,事實證明,神秘的行為取決於L1緩存是否了解L2緩存中的內容。 所附的單元測試旨在成對執行,該對中的每個元素都在單獨的JVM中運行,以避免EHCache單身。

我認為行為良好的L1-> L2關系應該起作用的方式是,如果執行.put()時沒有錯誤,則應該能夠在沒有問題的情況下立即執行相同鍵的get()。沒有其他同時運行的線程弄亂了東西)。 但是,使用Terracotta EHCache時,如果該.put()需要撤消某些操作,則不會發生驅逐,並且put()會被靜默忽略,除非L1客戶端“知道”可以撤消的密鑰。 在* JVM2測試中,它使用.getAllWithLoader()找出其他那些鍵,然后* JVM2測試按預期工作。

因此,為了解決原始問題,我們要做的是使它成為定期使客戶端執行.getAllWithLoader()的方法。 然后,我們可以確保遵守所有驅逐規則。

package com.mine;

import java.io.Serializable;

import junit.framework.TestCase;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.TerracottaClientConfiguration;
import net.sf.ehcache.config.TerracottaConfiguration;

public class CacheEvictionTest extends TestCase {

    private static final String SERVER = "localhost:9510";
    private CacheManager cacheManager;
    private Cache cache;
    private final Serializable keyA = "a";
    private final Serializable keyB = "b";
    private final Serializable keyC = "c";

    @Override
    protected void setUp() throws Exception {
        Configuration configuration = new Configuration();
        TerracottaClientConfiguration terracottaConfig = new TerracottaClientConfiguration();
        terracottaConfig.setUrl(SERVER);
        configuration.addTerracottaConfig(terracottaConfig);

        int maxElementsInMemory = 1;
        int maxElementsOnDisk = 2;
        long timeToIdleSeconds = 15;
        long timeToLiveSeconds = 15;
        String cacheName = "TEST_CACHE";
        CacheConfiguration amoebaCache = new CacheConfiguration(cacheName, maxElementsInMemory).statistics(true)
                        .terracotta(new TerracottaConfiguration())
                        .logging(true)
                        .maxElementsOnDisk(maxElementsOnDisk)
                        .timeToIdleSeconds(timeToIdleSeconds)
                        .timeToLiveSeconds(timeToLiveSeconds);
        configuration.addCache(amoebaCache);
        configuration.addDefaultCache(new CacheConfiguration("default", 0));

        cacheManager = new CacheManager(configuration);
        cache = cacheManager.getCache(cacheName);
    }

    @Override
    protected void tearDown() throws Exception {
        if (cache != null) {
            cache.removeAll();
            cache.clearStatistics();
        }
    }

    public void testMaxElementOnDiskEvictionJVM1() throws Exception {
        cache.clearStatistics();

        cache.put(new Element(keyA, keyA));
        cache.put(new Element(keyB, keyB));

        cache = null;
    }

    public void testMaxElementOnDiskEvictionJVM2() throws Exception {
        assertEquals(2, cache.getSize());

        for (Object key : cache.getKeys()) {
            cache.get(key;
        }

        cache.put(new Element(keyC, keyC));

        assertEquals(2, cache.getSize());
        assertNotNull(cache.get(keyC));
    }

    public void testEvictsExpiredElementsFromDiskWhenNotInMemoryAndWeNeverKnewAboutItJVM1() throws Exception {
        cache.clearStatistics();
        cache.put(new Element(keyA, keyA));

        cache = null;
        cacheManager = null;
    }

    public void testEvictsExpiredElementsFromDiskWhenNotInMemoryAndWeNeverKnewAboutItJVM2() throws Exception {
        cache.clearStatistics();

        for (Object key : cache.getKeys()) {
            cache.get(key;
        }
        assertEquals(0, cache.getStatistics().getEvictionCount());

        Thread.sleep(20000);

        assertEquals(1, cache.getStatistics().getEvictionCount());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM