zzyugl / xmemcached

Automatically exported from code.google.com/p/xmemcached
Apache License 2.0
0 stars 0 forks source link

不知什么情况,一旦出现这种情况,就一直出现,报错信息见描述 #269

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
java.lang.IllegalStateException: Namespace key already has value.The key 
is:namespace:DictItem,and the value is:1383040902472``standB

at 
net.rubyeye.xmemcached.XMemcachedClient.getNamespace(XMemcachedClient.java:2690)
at 
net.rubyeye.xmemcached.XMemcachedClient.preProcessKey(XMemcachedClient.java:2644
)
at net.rubyeye.xmemcached.XMemcachedClient.get0(XMemcachedClient.java:1055)
at net.rubyeye.xmemcached.XMemcachedClient.get(XMemcachedClient.java:1016)
at net.rubyeye.xmemcached.XMemcachedClient.get(XMemcachedClient.java:1027)
at net.rubyeye.xmemcached.XMemcachedClient.get(XMemcachedClient.java:1049)

请问这是什么情况,如何解决?
解决完后请告知:domyj2eejob@gmail.com

谢谢!

Original issue reported on code.google.com by domyj2ee...@gmail.com on 29 Oct 2013 at 10:07

GoogleCodeExporter commented 9 years ago
简单地来讲就是你手工设置过namespace:DictItem这个值,这个值��
�是数字

Original comment by xzhu...@avos.com on 29 Oct 2013 at 10:42

GoogleCodeExporter commented 9 years ago
在命名空间DictItem中,设置了
memcachedClient.withNamespace(namespace, new MemcachedClientCallable<Void>() {
                public Void call(MemcachedClient client) {
                    client.set("abc", paramTimeout, "aa``en");
                }
            });
请问值不是实现Serilizable接口即可吗? 为什么一定要是数字呢?

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 5:35

GoogleCodeExporter commented 9 years ago
这个是什么东西?  ``standB

我估计是不是你的key有null或者空字符串的情况,导致不小心�
��改了namespace的值

Original comment by xzhu...@avos.com on 30 Oct 2013 at 5:59

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
刚测试过,毫无问题,memcached 1.4.13版本

        String namespace = "Dict";
        memcachedClient.withNamespace(namespace, new MemcachedClientCallable<Void>() {
            public Void call(MemcachedClient client)throws MemcachedException,
            InterruptedException, TimeoutException {
                    client.set("caseType", 0, "容器类型``caseType");
                    return null;
            }
    });

Original comment by xzhu...@avos.com on 30 Oct 2013 at 7:31

GoogleCodeExporter commented 9 years ago
@Test public void testXMemcached() {
        memcachedClient.flushAll();
        memcachedClient.invalidateNamespace("Dict");
     memcachedClient.withNamespace(namespace, new MemcachedClientCallable<Void>() {
    public Void call(MemcachedClient client) {
        client.set("caseType", 0, "容器类型``caseType");
    }
});
}
// 
以上代码执行会报错,其中``只是一个字符串,就是键盘左上角�
��那个键.

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 7:37

GoogleCodeExporter commented 9 years ago
不好意思,应该是 flushAll() 和 
invalidateNamespace()两个方法调用完后再调用withNamespace的set方法,
这样就会使错误重现

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 7:38

GoogleCodeExporter commented 9 years ago
再次测试,仍然毫无问题

        String namespace = "Dict";
        memcachedClient.flushAll();
        memcachedClient.invalidateNamespace(namespace);
        memcachedClient.withNamespace(namespace, new MemcachedClientCallable<Void>() {
            public Void call(MemcachedClient client)throws MemcachedException,
            InterruptedException, TimeoutException {
                    client.set("caseType", 0, "容器类型``caseType");
                    return null;
            }
    });

Original comment by xzhu...@avos.com on 30 Oct 2013 at 7:43

GoogleCodeExporter commented 9 years ago
在以上代码之前,memcached内已经存储了数据字典表的值,每次更
新数据字典后,会手动执行flushAll,invalidateNamespace,然后循环set��
�,然而在set值后,好像memcached服务器原先的值会造成干扰一样(�
��报错信息上来看):以下是报错信息:
DEBUG => 
com.capitalbio.soft.core.cache.memcached.XMemcachedUtils.flushAll(XMemcachedUtil
s.java:200) - 
Memcached: flush all memcached cache
WARN  => 
net.rubyeye.xmemcached.XMemcachedClient.buildConnector(XMemcachedClient.java:727
) - 
XMemcachedClient use Binary protocol
WARN  => 
com.google.code.yanf4j.core.impl.AbstractController.start(AbstractController.jav
a:372) - 
The Controller started at localhost/127.0.0.1:0 ...
WARN  => 
com.google.code.yanf4j.core.impl.AbstractController.addMainSession(MemcachedConn
ector.java:251) - 
Add a session: 192.168.6.253:11311
WARN  => 
com.google.code.yanf4j.core.impl.AbstractController.addMainSession(MemcachedConn
ector.java:251) - 
Add a session: 192.168.6.143:11411
DEBUG => 
com.capitalbio.soft.core.cache.memcached.XMemcachedUtils.invalidNamespace(XMemca
chedUtils.java:186) - 
Memcached: invalid namespace: Dict
DEBUG => 
com.capitalbio.soft.core.cache.memcached.XMemcachedUtils.setWithNamespace(XMemca
chedUtils.java:67) - 
Memcached: update cache Ky``e in namespace: Dict
ERROR => 
com.capitalbio.soft.core.cache.memcached.XMemcachedUtils.setWithNamespace(XMemca
chedUtils.java:82) - 

java.lang.IllegalStateException: Namespace key already has value.The key 
is:namespace:Dict,and the value is:1383119108471

楼主可以先使用xmemcached存放一些数据到memcached服务器上,这里
使用的是"Spring3.1.4版本,xmemcache 1.4.3最新版

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 7:54

GoogleCodeExporter commented 9 years ago
从原理上说这种情况是不可能出现的,因为我写的code,自己�
��清楚,并且我们也在用namespace,从来没有遇到过问题。

你这里的问题就是认为干扰了namespace对应的value,默认这个val
ue是个long字段的时间戳,被认为加上了错误的字符串,如果��
�是手工设置namespace的值,比如 set(namespace, 0, 
value),那么就是有空的值被加入到的namespace下。

Original comment by xzhu...@avos.com on 30 Oct 2013 at 7:59

GoogleCodeExporter commented 9 years ago
简单来说,如果你的namespace是DictItem,那么就不能给DictItem设�
��一个值,它会默认被赋予一个时间戳,xmemcached自动维护。

Original comment by xzhu...@avos.com on 30 Oct 2013 at 8:00

GoogleCodeExporter commented 9 years ago
好像是调用invalidateNamespace("Dict")方法会自动将键为namespace:Dict
项从原值为1383121946793更改成1383122942911牱閮ㄤ綅``END,然后就会
报上面的错,这里使用的是二进制协议,我认为是不是invalidateNa
mespace("Dict")方法有问题,即使我把memcached服务器全部重启,里面
一个值也没有,直接调用invalidateNamespace,然后调用memcachedClient.w
ithNamespace("Dict", new MemcachedClientCallable<Void>() {
            public Void call(MemcachedClient client)throws MemcachedException,
            InterruptedException, TimeoutException {
                    client.set("caseType", 0, "容器类型``caseType");
                    return null;
            }就会出错,我觉得问题在于invalidateNamespace上,一旦namespace被invalid,则此命名空间不能再被set值了
请楼主查看

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 8:52

GoogleCodeExporter commented 9 years ago
找到问题了,应该是二进制协议带来的问题,感谢你的反馈��
�建议你暂时还是用text协议,比较成熟稳定。

Original comment by xzhu...@avos.com on 30 Oct 2013 at 9:17

GoogleCodeExporter commented 9 years ago
另外invalidateNamespace后,好像在此命名空间下的值没有从服务器
上消失,即使再get一次也不会消失,而仅是获取不到了,请问那��
�方法是销毁对应命名空间下的所有的项的? 
好像仅有flushAll方法有此效果

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 9:21

GoogleCodeExporter commented 9 years ago
不会销毁,只是让你get不到。最终过期或者LRU替换出去。

建议你用text协议重新测试。

Original comment by xzhu...@avos.com on 30 Oct 2013 at 9:24

GoogleCodeExporter commented 9 years ago
如果invalid后,设置过期时间为0(即:永不过期),请问LRU算法是由m
emcached服务器执行还是由XMemcached在运行过程中定时执行?
如果invalidateNamespace和set方法重复调用次数很多,且服务器内存
不大,是否会导致再也set不进去的现象或服务器报错?
如果问题有些基础,还望楼主告知

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 9:30

GoogleCodeExporter commented 9 years ago
LRU是memcached的机制,0也不是永不过期,而是30天
理论上不会报错,除非memcached自身有bug。xmemcached只是个客户�
��。

Original comment by xzhu...@avos.com on 30 Oct 2013 at 9:31

GoogleCodeExporter commented 9 years ago
建议在invalidateNamespace()方法里面加入类似于flushAll类似的移除
效果,以避免memcached服务器的LRU算法把不经常访问但不应该移�
��的移除了,而已被invalidNamespace的项还留在内存中,而造成不必
要的重新set. 或另外提供一方法也可

Original comment by domyj2ee...@gmail.com on 30 Oct 2013 at 9:46

GoogleCodeExporter commented 9 years ago
这是没有办法实现的。memcached不支持namespace,这个namespace是xm
emcached额外实现的。

Original comment by xzhu...@avos.com on 30 Oct 2013 at 9:48