当前位置: 首页 > 工具软件 > spy2servers > 使用案例 >

spy membase cancelled 问题

葛俊
2023-12-01

 

在使用membase时,发现久不久会出现下面问题:

 

WARN net.spy.memcached.protocol.binary.BinaryMemcachedNodeImpl:  Operation canceled because authentication or reconnection and authentication has taken more than one second to complete.
java.util.concurrent.ExecutionException: java.lang.RuntimeException: Cancelled
        at net.spy.memcached.internal.OperationFuture.get(OperationFuture.java:75)
        at net.spy.memcached.internal.GetFuture.get(GetFuture.java:37)

 

网上查询的讨论结果为:

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.

 

I believe you can set OperationState.RETRY in the connection factory builder if you want the operation to be sent again. Operations are likely cancelled by default because if an operation fails the user might not really care since doing the operation again would take too long for the application.

 

经过查证发现可能是网络延迟,导致的问题,membase默认的时间太短。
解决思路,方法连接时间,和操作时间,使得不容易出现cancelled。

由于MemcachedClient不能设置这些参数,所有改用了MemcachedClientFactoryBean来生成MemcachedClient的方法。

 

		String url="";
		String username="";
		String password="";
		MemConnection memConn = null;
		if (url != null && username != null && password != null) {
			MemcachedClient mc = null;
			// Then connect using the ConnectionFactoryBuilder. Binary is required.
			try {
				AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" }, new PlainCallbackHandler(
						username, password));
				
				/*
				 *传统的MemcachedClient生成方式,但是无法设置连接时间的问题,导致连接很容易超时
				 ×
				mc = new MemcachedClient(new ConnectionFactoryBuilder().setProtocol(Protocol.BINARY).setAuthDescriptor(ad)
						.build(), AddrUtil.getAddresses(url));

				memConn = new MemConnectionImpl(mc);
				*/
				
				/×
				 × 此工厂模式可以通过spring来配置,这里使用代码生成方式
				 ×/
				MemcachedClientFactoryBean memcachedClientFactoryBean = new MemcachedClientFactoryBean();
				memcachedClientFactoryBean.setServers(prop.getProperty("url"));
				memcachedClientFactoryBean.setAuthDescriptor(ad);
				memcachedClientFactoryBean.setProtocol(Protocol.BINARY);
				
				SerializingTranscoder transcoder=new SerializingTranscoder();
				transcoder.setCompressionThreshold(1024);
				memcachedClientFactoryBean.setTranscoder(transcoder);
				
				/×
				 ×解决访问超时的方法,设置运行时间和从新连接时间长些
				 ×/
				memcachedClientFactoryBean.setOpTimeout(10000); 
				memcachedClientFactoryBean.setMaxReconnectDelay(10000);
				
				memcachedClientFactoryBean.setTimeoutExceptionThreshold(1998); 
				memcachedClientFactoryBean.setLocatorType(Locator.CONSISTENT);
				memcachedClientFactoryBean.setFailureMode(FailureMode.Retry); 
				memcachedClientFactoryBean.setUseNagleAlgorithm(false);
				
				mc=(MemcachedClient)memcachedClientFactoryBean.getObject();
				memConn = new MemConnectionImpl(mc);

			} catch (Exception ex) {
				ex.printStackTrace();
			}

		}


 

 类似资料: