1

因此,我尝试使用 memcached 和 add() 的存储来实现分布式锁,前提是不存在合约(Java 和 spymemcached,但当然适用于任何语言)。当然,如果一个实例消失了,那么我们就会失去锁,所以我们想加锁 3 次(例如 MyLock1、MyLock2、MyLock3),这很可能会散列到 3 个不同的实例。

但是,我已经意识到,如果一个实例的哈希值下降,那么显然会发生变化(使用 spymemcached 的重新分发故障模式),因此当再次尝试 add() 锁时,所有 3 个锁的哈希值可能不会匹配 memcached 集群中剩余的 2 个锁中的任何一个。

那么......对于使用 memcached 的分布式锁还有其他想法吗?或者基本上不可能像我所指的那样做一个有保证的锁?

编辑:好的,所以在查看 spymemcached 源代码时,对于 Redistribute 模式,它只是转到其列表中的下一个活动 memcached 实例,而不是重新散列任何东西,所以它应该可以正常工作。

4

3 回答 3

3

你不能,至少不能可靠。memcached 不对数据保留做任何保证——作为缓存,它可能会在任何时候丢弃数据而不会发出警告。即使 memcache 实例似乎有可用空间,它也可能由于slab 约束而不得不驱逐数据。

如果您需要分布式锁定,则需要寻找其他地方——memcached 是不适合这项工作的工具。对于它的价值,MySQL 有锁:http ://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html

于 2011-06-30T17:49:57.840 回答
2

如果你真的想使用 memcached 来避免在你的环境中引入更多的东西/复杂性,那么考虑一个非常小但专用的 memcached 配置,仅用于锁定。

但是,如果您对不依赖 memcached 的解决方案持开放态度,那么我个人会使用zookeeper在 java 中实现分布式锁。我还会使用Netflix curator utils来简化此操作。

于 2011-06-30T17:54:43.513 回答
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/

希望能帮助到你。

于 2012-01-17T01:45:37.777 回答