memcached服务器重新启动后出现意外行为。如何配置/纠正它?

时间:2011-11-09 10:25:12

标签: memcached spymemcached

我有一个持久连接池(Memcached客户端)。数据正在缓存在memcached服务器中。如果重新启动memcached服务器后,我尝试使用池中的客户端获取缓存数据,我得到以下异常:

java.util.concurrent.ExecutionException: java.lang.RuntimeException: Cancelled
    at net.spy.memcached.MemcachedClient$OperationFuture.get(MemcachedClient.java:1662)
    at net.spy.memcached.MemcachedClient$GetFuture.get(MemcachedClient.java:1708)
    at com.eos.gds.cache.CacheClient.get(CacheClient.java:49)

我尝试获取缓存数据时,仅在重启后第一次获得此异常。我做了很多搜索。但无法找到确切原因。

5 个答案:

答案 0 :(得分:2)

Spymemcached有一堆内部队列,在将它们实际发送到memcached之前放置操作。这里发生的是你进行操作,然后在通过线路发送操作之前或者从memcached收到响应之前,Spymemcached意识到连接已经丢失。因此,Spymemcached取消了飞行中的所有操作,然后重新建立连接。

当你在Future上调用get()时,由于Spymemcached取消了操作,因此抛出异常。我建议在这里做的是捕获你使用Spymemcached进行的每个操作的所有异常,然后根据错误重新尝试忘记它的操作。如果它是一个例子,并且你的memcached服务器集群出现故障,那么你可能会忘记它,因为缓存将为空,但你可能想要重试一个集合。

答案 1 :(得分:1)

为每个新客户端运行一次MemcachedClient.getStats(),这将解决取消问题。

答案 2 :(得分:0)

我遇到了完全相同的问题并通过处理异常直到成功来修复它

while(true){
 try{
  memcacheclient.get(key);
  break;
 }
 catch(java.util.concurrent.CancellationException e ){
  log.info("cache cancelled");
 }
}

答案 3 :(得分:0)

我有同样的问题。我正在使用Spymemcached客户端连接Memcache服务器。

我找到了this

必须存在连接问题。

参考:https://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/internal/OperationFuture.java

答案 4 :(得分:0)

过去几天寻找解决方案。发布以防他人使用。

我们的ServletContextListener实现在contextInitialized上获得了一个新的MemcachedClient(...),然后在contextDestroyed上调用了MemacachedClient方法shutdown()。我将始终在我发送的第一个请求上收到CancellationException或ExecutionException。 (两者都暗示了错误消息,但是我能够捕获到ExecutionException。)

解决方案:从shutdown()切换为shutdown(1,TimeUnit.SECONDS)

现在,get调用第一次运行成功。

我不能确定解释contextDestroyed调用是如何干扰请求的常规处理的。我最好的 guess 是spymemcached的单线程以某种方式在servlet之间共享,因此,当创建servlet来处理构建过程中验证步骤发送的请求时,它将在第一个被销毁之前被销毁。我将发送的请求,然后我的请求的servlet使用的MemcachedClient会尝试使用相同的线程,并从关闭中获取异常。

(当我们了解到我们的Web应用与内存缓存服务器的打开连接过多时,我们的团队已经确定需要关闭电话。)