memcahe本身提供有对getMulti的支持 但是memecahed java client中的getMulti方法是使用多线程并发请求来实现的 为了减少socket的消耗添加了一个对getMulti(协议中为get key1 key2 ...)协议支持的方法
在AscIIClient中增加下面方法
private Map<String, Object> doMget(MultiKeyBuffer multiKeyBuffer) {
Map<String, Object> valuesMap = new HashMap<String, Object>();
while(multiKeyBuffer.hasNext()) {
String multiKey = multiKeyBuffer.next();
if(multiKey == null) return null;
// get SockIO obj using cache key
SchoonerSockIO sock = pool.getSock(multiKey, null);
if (sock == null) {
if (errorHandler != null)
errorHandler.handleErrorOnGet(this, new IOException("no socket to server available"), multiKey);
return null;
}
String cmdLine = "get " + multiKey;
try {
sock.writeBuf.clear();
sock.writeBuf.put(cmdLine.getBytes());
sock.writeBuf.put(B_RETURN);
// write buffer to server
sock.flush();
SockInputStream input = new SockInputStream(sock, Integer.MAX_VALUE);
int oneTimeReadMaxCount = 32;
jump:
while(oneTimeReadMaxCount-- > 0){
String responseKey = "";
int dataSize = 0;
int flag = 0;
boolean stop = false;
StringBuilder sb = new StringBuilder();
int b;
int index = 0;
while (!stop) {
/*
* Critical block to parse the response header.
*/
b = input.read();
if (b == ' ' || b == '\r') {
switch (index) {
case 0:
if (END.startsWith(sb.toString()))
break jump;
case 1:
responseKey = sb.toString();
break;
case 2:
flag = Integer.parseInt(sb.toString());
break;
case 3:
// get the data size
dataSize = Integer.parseInt(sb.toString());
break;
}
index++;
sb = new StringBuilder();
if (b == '\r') {
input.read();
stop = true;
}
continue;
}
sb.append((char) b);
}
Object o = null;
input.willRead(dataSize);
// we can only take out serialized objects
if (dataSize > 0) {
if (NativeHandler.isHandled(flag)) {
// decoding object
byte[] buf = input.getBuffer();
if ((flag & F_COMPRESSED) == F_COMPRESSED) {
GZIPInputStream gzi = new GZIPInputStream(new ByteArrayInputStream(buf));
ByteArrayOutputStream bos = new ByteArrayOutputStream(buf.length);
int count;
byte[] tmp = new byte[2048];
while ((count = gzi.read(tmp)) != -1) {
bos.write(tmp, 0, count);
}
// store uncompressed back to buffer
buf = bos.toByteArray();
gzi.close();
}
if (primitiveAsString) {
o = new String(buf, defaultEncoding);
} else
o = NativeHandler.decode(buf, flag);
} else if (transCoder != null) {
// decode object with default transcoder.
InputStream in = input;
if ((flag & F_COMPRESSED) == F_COMPRESSED)
in = new GZIPInputStream(in);
if (classLoader == null)
o = transCoder.decode(in);
else
o = ((ObjectTransCoder) transCoder).decode(in, classLoader);
}
valuesMap.put(responseKey, o);
}
input.willRead(Integer.MAX_VALUE);
input.getLine();//跳过每一个value发送完成的\r\n
}
} catch (Exception ce) {
try {
sock.trueClose();
} catch (IOException e) {
log.error("++++ failed to close socket : " + sock.toString());
}
sock = null;
} finally {
if (sock != null) {
sock.close();
sock = null;
}
}
}
return valuesMap;
}
@Override
public Map<String, Object> mget(String[] keys) {
if (keys == null || keys.length == 0) {
log.error("keys is null for mget()");
return null;
}
MultiKeyBuffer buf = new MultiKeyBuffer(keys);
return doMget(buf);
}
/*这里设置每次使用getMulti最多执行多少个key(忘了memcache支持一次多少个key了...)*/
private static int per_multikey_max_size = 32;
class MultiKeyBuffer{
/**原始数据*/
private final String[] keys;
/**当前已经取到了哪个位置(从0开始)*/
private int position;
/**数组的长度*/
private final int size;
public MultiKeyBuffer(String[] keys) {
this.keys = keys;
size = keys.length;
}
/**
* 获取下一个multiKey
* @return
*/
public String next(){
if(hasNext()){
int limit = Math.min(size, position + per_multikey_max_size);
StringBuilder multiKeySb = new StringBuilder();
while(position < limit){
String key = keys[position];
try {
key = sanitizeKey(key);
} catch (UnsupportedEncodingException e) {
log.error("failed to sanitize your key!", e);
return null;
}
multiKeySb.append(" ").append(key);
position ++;
}
return multiKeySb.substring(1);
}
return null;//调用hasNext()防止执行到该行
}
public boolean hasNext(){
return position < size;
}
}
在父类MemcachdClient中增加
public Map<String, Object> mget(String[] keys) {
return client.mget(keys);
}
分享到:
相关推荐
例如,使用`getMulti()`方法可以一次性获取多个键对应的值: ```java Collection<String> keys = Arrays.asList("key1", "key2", "key3"); Map, Object> values = memcachedClient.getMulti(keys); for (Map.Entry,...
- **批量操作**:`getMulti`方法支持一次性获取多个键的值,`setMulti`用于批量设置键值对。 - **过期时间**:除了固定的过期时间,还可以设置相对时间,如`client.set("key", 0, "value")`表示永不超时。 - **操作...
在Java项目中使用`spymemcached`,首先需要将其添加为项目依赖。通常,这可以通过Maven或Gradle的依赖管理完成。在Maven的`pom.xml`文件中,添加如下依赖: ```xml <groupId>net.spy</groupId> <artifactId>...
- **添加数据**:使用`MemcachedClient`的`set`方法可以将数据存储到缓存中,指定一个键和一个过期时间。 - **获取数据**:通过键来检索数据,使用`get`方法。 - **删除数据**:如果不再需要某个缓存项,可以使用...
**Mencache 使用指南** Mencache,全称为“Memory Cache”,是一款高性能、轻量级的内存缓存系统...理解其工作原理和使用方法,能够帮助开发者有效地利用这一工具,为网站或应用带来更快的响应速度和更好的用户体验。
易语言Memcached协议客户端模块源码,Memcached协议客户端模块,Initialize,Connect,Timeout,Exptime,IsRunning,RunStorageCommand,AnalyzeMessage,Set,Add,Replace,Delete,Incr,Decr,Version,Get,GetMulti,...
MUC,全称为Multi-User Chat,是XMPP协议中用于实现多用户聊天室的功能。在Openfire中,MUC允许用户创建临时或永久的聊天室,类似于QQ群或者Discord频道。 在默认情况下,Openfire的MUC功能可能无法完全满足需求,...
例如,可以使用`client.setMulti()`和`client.getMulti()`进行批量设置和获取多个键值对。 六、异常处理与最佳实践 在使用`node-memcached`时,应妥善处理异常,避免程序因网络问题或Memcached服务器故障而中断。...
- 创建`Memcached`实例,通过`new Memcached()`来初始化连接,并使用`addServer()`方法添加服务器地址和端口。 3. **Memcached的高级配置** - **持久连接**:使用`pconnect()`代替`connect()`,保持客户端与...
3. **LICENSE**:文件包含了该扩展的授权协议,规定了如何使用、修改和分发代码的规则,对于开源软件而言,理解许可协议是遵守法律的基础。 4. **php_memcache.pdb**:这是一个程序数据库文件,用于在开发阶段调试...
开源+示例(模块代码中有详细的使用方法) 参照网上的 Memcached 协议实现的客户端,可靠性方面应该还是不错的,和昨天的 Redis 协议一样,应该能适用于正式项目。 总共耗费 2 个多小时完成,不可否认,用纯易语言实现...
通过深入理解和熟练使用 Memcached-2.3.1 API,开发者能够构建高效、可靠的分布式缓存系统,为应用程序提供快速的数据访问和减轻数据库压力。在阅读 `memcached-2.3.1-javadoc` 文档时,应重点理解每个方法的功能、...
使用`setMulti()`和`getMulti()`方法进行批量操作。 2. 自动过期: 除了手动设置过期时间,还可以使用`add()`方法,当键已存在时,数据将不会被添加,这可以避免覆盖已存在的缓存。 3. 缓存预热: 在高流量网站上...
nds 软件包github.com/qedus/nds是Google App ... 标准的datastore.GetMulti , datastore.PutMulti和datastore.DeleteMulti函数的另一个好处是,每个调用最多只能使用1000、500和500个实体。 此包中的nds.GetMulti
Memcache提供了一个名为`getMulti`的函数,用于批量获取多个键的值。在上述描述中,我们看到一个示例,尝试通过`getMulti`获取15个特定ID(如31639, 33878等)的值。然而,当使用单台Memcache服务器时,`getMulti`...
`Memcache`是较早的客户端,支持非面向对象的接口,而`Memcached`则使用libmemcached库,仅支持面向对象接口,提供了更多方法,例如`getMulti`、`getByKey`和`addServers`。`Memcached`还支持二进制协议,这使得它在...
如果没有任何分隔符被找到,函数会设置`t`为0,并将整个原始字符串添加到`linkstr`中,表示字符串没有被切割。 需要注意的是,`getmulti`函数并没有使用`split()`函数,而是通过比较和查找分隔符的方式来实现字符串...