标签:
使用spymemcached客户端,通过wireshark抓包,更清晰的看到memcached的命令。
先来一个简单的demo:
package spymc; import java.io.IOException; import java.net.InetSocketAddress; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClient; public class TestSpyMc { public static void main(String[] args) throws IOException { MemcachedClient c = new MemcachedClient(new InetSocketAddress("aliyun.9game.cn", 11211)); c.set("abc", 3600, "hello"); System.err.println(c.get("abc")); //CASValue<Object> vasValue = c.gets("abc"); //CASResponse resp= c.cas("abc", vasValue.getCas(), "pre"); //System.out.println(resp.name()); //resp= c.cas("abc", vasValue.getCas(), "after"); //System.out.println(resp.name()); c.shutdown(); } }
抓包的结果会看到:
set abc 0 3600 5 hello get abc STORED VALUE abc 0 5 hello END
粉色代表请求,蓝色代表响应。spymemcached在上一节说了,spymemcached是非阻塞的。所以发出set指令响应之前,get命令都发出去了。
然后看看 gets 和cas。尝试做两次cas操作:
package spymc; import java.io.IOException; import java.net.InetSocketAddress; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClient; public class TestSpyMc { public static void main(String[] args) throws IOException { MemcachedClient c = new MemcachedClient(new InetSocketAddress("aliyun.9game.cn", 11211)); //c.set("abc", 3600, "hello"); //System.err.println(c.get("abc")); CASValue<Object> vasValue = c.gets("abc"); CASResponse resp= c.cas("abc", vasValue.getCas(), "pre"); System.out.println(resp.name()); resp= c.cas("abc", vasValue.getCas(), "after"); System.out.println(resp.name()); c.shutdown(); } }
首先, 输出结果是:
OK EXISTS
抓包看到的是:
gets abc VALUE abc 0 3 2272929 pre END cas abc 0 0 3 2272929 pre STORED cas abc 0 0 5 2272929 after EXISTS
gets 和cas 通过版本号实现原子性操作,重复两次cas,相同的版本号,第二次是失败的。
然后试试gets和sets之间,做一次set操作。java代码:
package eGroup.spymcTest; import java.io.IOException; import java.net.InetSocketAddress; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClient; public class TestSpyMc { public static void main(String[] args) throws IOException { MemcachedClient c = new MemcachedClient(new InetSocketAddress("aliyun.9game.cn", 11211)); CASValue<Object> vasValue = c.gets("abc"); c.set("abc", 3600, "hello sb"); CASResponse resp= c.cas("abc", vasValue.getCas(), "pre"); System.out.println(resp.name()); c.shutdown(); } }
IDE控制台输出:
EXISTS
抓包得出:
gets abc VALUE abc 0 8 2279149 hello sb END set abc 0 3600 8 hello sb cas abc 0 0 3 2279149 pre STORED EXISTS
set成功,cas就失败了。
可见, gets&cas,是乐观锁的概念。并不是‘独占’数据的。
最后试试重复add操作。java代码:
c.add("addTest", 3600, "hello");
c.add("addTest", 3600, "hello");
抓包得出:
add addTest 0 3600 5 hello add addTest 0 3600 5 hello STORED NOT_STORED
mc 的add指令,如果有key存在了,后续的add操作是会失败的。单点memcached的话可以当互斥锁来玩。
以下是对指令的一些总结:
标签:
原文地址:http://www.cnblogs.com/ELMND/p/4598610.html