memcached 服务器重新启动后出现意外行为。如何配置/纠正它?
我有一个持久连接池(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)
仅在重新启动后当我尝试获取缓存数据时第一次收到此异常。我做了很多搜索。但无法找到具体原因。
I have a pool of persistent connections(Memcached clients). Data are being cached in the memcached server. If after restarting the memcached server, I try to get the cached data using the client from the pool, I m getting the below exception:
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)
I get this exception only for the first time after the restart when I try to get the cached data. I did a lot of search. But unable to find the exact reason for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
几天来一直在寻找解决方案。发布以防对其他人有帮助。
我们的 ServletContextListener 实现是在 contextInitialized 上获取一个新的 MemcachedClient(...) ,然后在 contextDestroyed 上调用 MemcachedClient 方法 shutdown() 。在我发送的第一个请求上,我总是会收到 CancellationException 或 ExecutionException。 (错误消息暗示了两者,但我能够捕获 ExecutionException。)
解决方案:从 shutdown() 切换到 shutdown(1, TimeUnit.SECONDS)
现在 get 调用在第一次运行时就成功了。
我无法确定 contextDestroyed 调用如何干扰请求的常规处理。我最好的猜测是,spymemcached 的单线程以某种方式在 servlet 之间共享,因此当创建 servlet 来处理构建过程的验证步骤发送的请求时,它将在第一个请求之前被销毁我要发送的请求,然后我的请求的 servlet 使用的 MemcachedClient 将尝试使用同一线程并受到关闭异常的影响。
(当我们得知我们的 Web 应用程序与 memcached 服务器有太多开放连接时,我们的团队不久前就确定需要调用 shutdown 。)
Been searching for days for a solution. Posting in case it helps someone else.
Our implementation of ServletContextListener was getting a new MemcachedClient(...) on contextInitialized, and would then call the MemacachedClient method shutdown() on contextDestroyed. I would always get a CancellationException or ExecutionException on the first request I would send. (The error messaging alluded to both, but an ExecutionException is what I was able to catch.)
Solution: switched from shutdown() to shutdown(1, TimeUnit.SECONDS)
Now the get call succeeds the very first time that it is run.
I cannot explain for sure how the contextDestroyed call was interfering with the regular handling of the request. My best guess is that spymemcached's single thread somehow gets shared between servlets, and so when a servlet was created to handle a request sent by a verification step of our build process, it would get destroyed prior to the first request I would send, and the MemcachedClient my request's servlet was using would then try to use that same thread and get hit with the exceptions from the shutdown.
(Our team had established the need to call shutdown a while back when we learned our web app had too many open connections to our memcached server.)
我有同样的问题。我正在使用 Spymemcached 客户端连接 Memcache 服务器。
我发现
一定是连接有问题。
参考: https://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/internal/OperationFuture.java
I had the same issue. I am using Spymemcached client to connect with Memcache server.
I found
.
There must be a connection issue.
Ref: https://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/internal/OperationFuture.java
为每个新客户端运行一次 MemcachedClient.getStats() ,这将解决取消问题。
Run MemcachedClient.getStats() for each new client once and that will fix the cancelations issue.
我遇到了完全相同的问题并通过处理异常来修复它直到成功
I ran into the exact same problem and fix it by handling the exception until success
Spymemcached 有一堆内部队列,操作在实际发送到 memcached 之前先放入其中。这里发生的情况是,您执行一个操作,然后在通过网络发送该操作之前或从 memcached 收到响应之前,Spymemcached 意识到连接已丢失。因此,Spymemcached 取消所有正在进行的操作,然后重新建立连接。
当您在 Future 上调用 get() 时,由于 Spymemcached 取消了该操作,因此会引发异常。我建议在这里做的是捕获您使用 Spymemcached 执行的每个单独操作的所有异常,然后根据错误,重试该操作或只是忘记它。例如,如果它是一个 get 并且您的 memcached 服务器集群出现故障,那么您可能会忘记它,因为缓存将为空,但您可能想重试一组。
Spymemcached has a bunch of internal queues that operations are placed in before they are actually sent out to memcached. What is happening here is that you do an operation and then before that operation is sent over the wire or before a response is received from memcached, Spymemcached realizes that the connection has been lost. As a result Spymemcached cancels all operations in flight and then reestablishes the connection.
When you call get() on the Future then since the operation was cancelled by Spymemcached an exception is thrown. What I recommend doing here is catching all exceptions on every individual operation you do with Spymemcached and then, depending on the error, either retrying the operation of just forgetting about it. If it's a get for example and your cluster of memcached servers goes down then you can probably forget about it since the cache will be empty, but you will probably want to retry a set.