2015-04-15 192 views
-1

我們有一個用例,我們希望有一個內存緩存,可以用不同的TTL存儲密鑰和值。我們知道一些記憶緩存像Guava,Hazelcast和Ehcache。我們使用番石榴嘗試過,但它存在使用expireAfterAccess和expireAfterWrite方法決定TTL的問題。這些將對緩存中的所有行具有恆定值。所以,這就是問題所在。所以,這裏所有的數據都會在寫入X小時後過期。雖然TTL會有所不同。但是我希望在設置關鍵值和值對的時候,我可以在那個時候設置TTL。應該使用哪個內存中緩存?

此外,我們正在使用dropwizard框架,所以它很好,這是在內存緩存中很容易與DropWizard框架集成。

請建議一些內存緩存,我們應該使用我們的用例。

感謝

回答

1

我前一段時間是在相同的情況下,並沒有發現番石榴的緩存爲我用的情況下非常有用的;它看起來有點複雜。我在.NET尋找類似HttpRuntime.Cache的東西。由於這不是一個很重要的功能,我決定儘快自己實現它,然後再回到它。它可能是錯誤的或不是最優化的。

我已經使用SHA256(256符合FIPS合規性)來保持它們的散列,所以我可以快速找到它們;但是你的用例可能有更好的方法。另外,我的對象中有過期時間,所以您可能需要修改代碼以在某處存儲過期時間。

private final ExecutorService executorService; 
    private final ConcurrentHashMap<String, MyObject> objectCache = new ConcurrentHashMap<>(); 
    private Instant lastObjectCacheCleanupTime = Instant.now(); 
    private static final TemporalAmount cacheCleanupFrequency = Duration.ofHours(1); 

    private void cacheObject(String encodedObject, MyObject object) { 
    executorService.submit(() -> { 
     objectCache.put(DigestUtils.sha256Hex(encodedObject), object); 

     synchronized (objectCache) { 
     if (Instant.now().isAfter(lastObjectCacheCleanupTime.plus(cacheCleanupFrequency))) { 
      lastObjectCacheCleanupTime = Instant.now(); 
      objectCacheCleanup(); 
     } 
     } 
    }); 
    } 

    private Optional<MyObject> getObjectFromCache(String encodedObject){ 
    String digest = DigestUtils.sha256Hex(encodedObject); 

    if (!objectCache.containsKey(digest)) { 
     return Optional.empty(); 
    } 

    MyObject myObject = objectCache.get(digest); 

    if (myObject.isExpired()) 
     objectCache.remove(digest); 
     return Optional.empty(); 
    } 

    return Optional.of(myObject); 
    } 


    private void objectCacheCleanup() { 
    for (Map.Entry<String, MyObject> digestObjectEntry : objectCache.entrySet()) { 
     if (digestObjectEntry.getValue().isExpired()) { 
     objectCache.remove(digestObjectEntry.getKey()); 
     } 
    } 
    } 
1

您可以使用Memcached的。 Java有不同的memcached客戶端 https://code.google.com/p/memcached/wiki/Clients#Java

我已經使用spymemcached客戶端。 來自實例:https://code.google.com/p/spymemcached/wiki/Examples

//獲取連接到多臺服務器分佈式緩存客戶端

MemcachedClient c=new MemcachedClient(
     AddrUtil.getAddresses("server1:11211 server2:11211")); 

//嘗試得到一個值,最多5秒,並取消,如果它不返回

Object myObj=null; 
Future<Object> f=c.asyncGet("someKey"); 
try { 
    myObj=f.get(5, TimeUnit.SECONDS); 
} catch(TimeoutException e) { 
    // Since we don't need this, go ahead and cancel the operation. This 
    // is not strictly necessary, but it'll save some work on the server. 
    f.cancel(false); 
    // Do other timeout related stuff 
} 

在同樣的方式,你可以用不同的TTL設定值

Future<Object> f=c.set(key, ttl, data); 

在dropwizard可以實現管理接口initalizing和回採memchached客戶 http://dropwizard.github.io/dropwizard/manual/core.html#managed-objects

public class MemcachedManger implements Managed { 
    private MemcachedClient client; 

    public MemcachedManger() { 
     // write a constructor for initializing custom dependencies of this class 
    } 

    @Override 
    public void start() throws Exception { 
     // create new object of memcachedClient 
     this.client=new MemcachedClient(AddrUtil.getAddresses("server1:11211 server2:11211")); 
    } 

    @Override 
    public void stop() throws Exception { 
     client.shutdown(); 
    } 


    // define get and put and any other custom methods using functionality provided by spymemchached client 
} 
0

聲明:我兵馬俑(Software AG公司)工作

Ehcache提供此功能。

一旦創建了一個Element,TTL和TTI可以在放入緩存之前設置。

相關問題