所以,我正在尝试使用memcached和add()的存储来实现分布式锁定,只有当不存在契约时(Java& spymemcached,但当然适用于任何语言)。当然,如果一个实例消失了,那么我们就失去了锁定,所以想到了锁定3次(例如MyLock1,MyLock2,MyLock3),它很可能会散列到3个不同的实例。
但是,我已经意识到,如果一个实例停止了哈希,那么显然会改变(使用spymemcached的Redistribute失败模式),因此当另一次尝试添加()锁时,可能是所有3的哈希值lock将与memcached集群中剩余的2个锁中的任何一个都不匹配。
那么......使用memcached的分布式锁的任何其他想法?或者基本上不可能像我指的那样做一个保证锁?
编辑:好的,所以在查看spymemcached源代码时,对于Redistribute模式,它只是转到它列表中的下一个活动的memcached实例,而不是重新散列任何东西,所以它应该可以正常工作。
答案 0 :(得分:3)
你不能,至少不可靠。 memcached不保证数据保留 - 作为缓存,它可以在任何时候丢弃数据而不发出警告。即使memcache实例似乎有空间可用,也可能因板块约束而逐出数据。
如果你需要分布式锁定,你需要寻找其他地方 - memcached是错误的工具。对于它的价值,MySQL有锁:http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html
答案 1 :(得分:2)
如果你真的想使用memcached来避免在你的环境中引入更多的东西/复杂性,那么考虑一个非常小但专用的memcached配置来锁定。
但如果您对不依赖于memcached的解决方案持开放态度,那么我个人会使用zookeeper在java中实现分布式锁。我还会使用Netflix curator utils来简化这一过程。
答案 2 :(得分:1)
如果您使用的是Java,我建议使用Hazelcast(1.9+),它支持跨群集的分布式锁,并且很容易创建。
Hazelcast保证如果持有锁的服务器发生故障,锁将被释放。
http://hazelcast.com/docs/1.9.4/manual/single_html/#Lock
此外,Hazelcast公开了与memcached相同的合同,因此如果您需要从JVM中访问它,您可以这样做(此示例演示了任何客户端都可以工作):
爪哇:
MemcachedClient client = new MemcachedClient(AddrUtil.getAddresses("10.20.17.1:5701 10.20.17.2:5701"));
client.set("key1", 3600, "value1");
System.out.println(client.get("key1"));
PHP:
<?php
$memcache = new Memcache;
$memcache->connect('10.20.17.1', 5701) or die ("Could not connect");
$memcache->set('key1','value1',0,3600);
$get_result = $memcache->get('key1'); //retrieve your data
var_dump($get_result); //show it
?>
1.9+的文件: http://hazelcast.com/docs/1.9.4/manual/single_html/
希望它有所帮助。