2016-08-21 62 views
1

我正在使用ehcache來控制用戶會話,每隔一段時間我都會在用戶登錄時看到此錯誤。使用getKeysWithExpiryCheck()方法時,ehcache keySet超時

net.sf.ehcache.constructs.nonstop.NonStopCacheException: keySet timed out 
    at net.sf.ehcache.constructs.nonstop.concurrency.NonStopCacheKeySet$NonStopCacheKeySetIterator$1.performClusterOperationTimedOut(NonStopCacheKeySet.java:103) 
    at net.sf.ehcache.constructs.nonstop.concurrency.NonStopCacheKeySet$NonStopCacheKeySetIterator$1.performClusterOperationTimedOut(NonStopCacheKeySet.java:96) 
    at net.sf.ehcache.constructs.nonstop.store.ExecutorServiceStore.executeClusterOperation(ExecutorServiceStore.java:1187) 
    at net.sf.ehcache.constructs.nonstop.store.NonstopStoreImpl.executeClusterOperation(NonstopStoreImpl.java:704) 
    at net.sf.ehcache.constructs.nonstop.concurrency.NonStopCacheKeySet$NonStopCacheKeySetIterator.<init>(NonStopCacheKeySet.java:96) 
    at net.sf.ehcache.constructs.nonstop.concurrency.NonStopCacheKeySet.iterator(NonStopCacheKeySet.java:56) 
    at net.sf.ehcache.Cache.getKeysWithExpiryCheck(v.java:1906) 
... 

official ehcache doucmentation說:「考慮您的使用情況是否需要過期鍵檢查,因爲這種方法需要很長時間,這取決於緩存設置,......」。

所以我不確定在ecache.xml中增加什麼超時來增加停止這個錯誤,即使20000 ms似乎對我來說已經足夠了,因爲文檔中還提到了每1000個條目大約需要200ms 。

這是使用的ehcache.xml。

<?xml version="1.0" encoding="UTF-8"?> 

<ehcache name="RelianceCache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> 


    <cache name="READ_USERS_CACHE" maxElementsInMemory="0" eternal="true" overflowToDisk="false"> 
     <terracotta clustered="true" valueMode="serialization" consistency="strong"> 
      <nonstop immediateTimeout="false" timeoutMillis="20000"> 
       <timeoutBehavior type="exception" /> 
      </nonstop> 
     </terracotta> 
    </cache> 


    <terracottaConfig url="TSA_SERVERS:TSA_PORT" rejoin="true" /> 
</ehcache> 

編輯: 參見the NonStopCacheKeySet implementation,錯誤被拋出的方法NonStopCacheKeySetIterator

+0

當發生這種情況時,您可以提供有關緩存大小的信息嗎?或者您的應用程序的生命週期與Terracotta服務器的啓動相比? –

+0

此高速緩存包含已登錄的用戶,所以我可以保證大小小於100個條目。我不太清楚我的應用程序的生命週期與兵馬俑服務器相比的意思。 – QuakeCore

+0

我在ehcache-core-2.6.8.jar中添加了一些調試消息,因爲原來的異常原因丟失了。 – QuakeCore

回答

0

增加超時並不能解決問題。 20個100秒的參賽作品非常長。

如果從應用程序邏輯的角度來看是合適的,我會考慮將timeoutBehavior更改爲timeoutBehavior="localReadsAndExceptionOnWrite"。請注意,localCacheEnabled屬性必須爲TRUE,這是默認值。

... 
    <terracotta clustered="true" localCacheEnabled="true" valueMode="serialization" consistency="strong"> 
     <nonstop immediateTimeout="false" timeoutMillis="20000"> 
      <timeoutBehavior type="localReadsAndExceptionOnWrite" /> 
     </nonstop> 
    </terracotta> 
    ... 

另一種解決方案可以被改變一致性爲缺省值consistency ="eventual"。這很可能會解決問題,但可能會導致緩存返回暫時過時的數據。


正如文檔所述:「考慮您的使用是否需要檢查過期的密鑰......」。是否有可能調整應用程序邏輯以使用Cache.getKey()而不是通過鍵列表進行迭代?