Неожиданное поведение после перезапуска сервера memcached.Как настроить / исправить это? - PullRequest
1 голос
/ 09 ноября 2011

У меня есть пул постоянных соединений (клиенты 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 ]

2 голосов
/ 09 ноября 2011

Spymemcached имеет множество внутренних очередей, в которые помещаются операции, прежде чем они будут отправлены в memcached. Здесь происходит то, что вы выполняете операцию, а затем перед тем, как эта операция отправляется по проводам или перед получением ответа от memcached, Spymemcached понимает, что соединение было потеряно. В результате Spymemcached отменяет все операции в полете, а затем восстанавливает соединение.

Когда вы вызываете get () для Future, то, поскольку операция была отменена Spymemcached, генерируется исключение. Здесь я рекомендую перехватывать все исключения для каждой отдельной операции, которую вы выполняете с помощью Spymemcached, а затем, в зависимости от ошибки, либо повторять операцию, либо просто забыв об этом. Если это, например, get, и ваш кластер серверов memcached выходит из строя, то вы, вероятно, можете об этом забыть, поскольку кеш будет пуст, но вы, вероятно, захотите повторить набор.

1 голос
/ 27 апреля 2017

Запустите MemcachedClient.getStats () для каждого нового клиента один раз, и это решит проблему отмены.

0 голосов
/ 24 июня 2019

В течение нескольких дней искали решение. Публикация на случай, если кому-то это поможет.

Наша реализация ServletContextListener получала новый MemcachedClient (...) для contextInitialized и затем вызывала метод MemacachedClient shutdown () для contextDestroyed. Я всегда получал бы CancellationException или ExecutionException при первом запросе, который я отправлю. (Сообщения об ошибках упоминались обоими, но я смог уловить исключение ExecutionException.)

Решение: переключено с shutdown () на shutdown (1, TimeUnit.SECONDS)

Теперь вызов get успешно выполняется при первом запуске.

Я не могу точно объяснить, как вызов contextDestroyed мешал регулярной обработке запроса. Моя лучшая догадка заключается в том, что отдельный поток spymemcached каким-то образом распределяется между сервлетами, и поэтому, когда сервлет был создан для обработки запроса, отправленного на этапе проверки нашего процесса сборки, он был бы уничтожен до первого запроса Я отправил бы, и MemcachedClient, который использовал сервлет моего запроса, попытался бы использовать тот же поток и получить исключения из завершения работы.

(Наша команда установила необходимость вызова shutdown некоторое время назад, когда мы узнали, что у нашего веб-приложения слишком много открытых соединений с нашим сервером memcached.)

0 голосов
/ 09 июня 2017

У меня была такая же проблема.Я использую клиент Spymemcached для соединения с сервером Memcache.

Я обнаружил this.

Должна быть проблема соединения.

Ссылка:https://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/internal/OperationFuture.java

0 голосов
/ 23 сентября 2014

Я столкнулся с точно такой же проблемой и исправил ее, обработав исключение до успеха

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