Гарантированная блокировка memcached

Итак, я пытаюсь реализовать распределенную блокировку, используя хранилище memcached и add(), только если не существует контракта (Java и spymemcached, но, конечно, применимо на любом языке). Конечно, если экземпляр исчезает, мы теряем блокировку, поэтому мы решили добавить блокировку 3 раза (например, MyLock1, MyLock2, MyLock3), что, скорее всего, приведет к хешированию в 3 разных экземпляра.

Но я понял, что если экземпляры теряют хэш, то, очевидно, они меняются (используя режим сбоя перераспределения spymemcached), и поэтому вполне вероятно, что когда будет предпринята еще одна попытка добавить () блокировки, хэши всех 3 блокировок не будут соответствует любой из двух оставшихся блокировок в кластере memcached.

Итак... какие еще идеи для распределенных блокировок с использованием memcached? Или в принципе невозможно сделать гарантированную блокировку, о которой я говорю?

РЕДАКТИРОВАТЬ: Итак, при просмотре исходного кода spymemcached для режима перераспределения он просто переходит к следующему активному экземпляру memcached в своем списке, а не повторно хеширует что-либо, поэтому он должен работать нормально.


person Drizzt321    schedule 30.06.2011    source источник
comment
Вы также должны рассматривать Membase как решение. Membase в основном memcached с сохраняемостью и репликацией, поэтому на самом деле она будет работать лучше, чем просто memcached для этой проблемы.   -  person mikewied    schedule 01.07.2011


Ответы (3)


Если вы действительно хотите использовать memcached, чтобы избежать внесения дополнительных вещей/сложностей в вашу среду, рассмотрите очень маленькую, но выделенную конфигурацию memcached только для блокировки.

Но если вы открыты для решений, которые не полагаются на memcached, то лично я бы использовал zookeeper для реализации распределенной блокировки в java. Я бы также использовал утилиты куратора Netflix, чтобы упростить эту задачу.

person jtoberon    schedule 30.06.2011
comment
Лично я бы предпочел использовать zookeeper или что-то подобное, но это одна из тех вещей, которые мы в настоящее время не используем, и с нашими (очень) ограниченными ресурсами будет другая вещь, и если это решение достаточно хорошее, чем это сработает для нас. - person Drizzt321; 30.06.2011
comment
Мой опыт работы с блокировкой/многопоточностью показал, что вы должны делать это правильно. Сколько разногласий по поводу этих замков будет? Как часто они приобретаются и как долго сохраняются? Может быть, мы сможем предложить менее технологичное решение, которое будет более надежным, чем memcached, и достаточно производительным для ваших целей. - person jtoberon; 30.06.2011
comment
Низкая конкуренция. Это больше, чтобы предотвратить загрузку одного и того же FTP-файла несколькими экземплярами. Частью процесса является добавление имени хоста экземпляра к файлу, чтобы предотвратить его загрузку другими потоками/экземплярами, но один из FTP-серверов, с которым нам нужно поговорить, имеет распределенную ФС, переименование которой иногда может занять несколько секунд для распространения, и поэтому, если несколько экземпляров подключены к нескольким местам, распространение которых еще не завершено, тогда он может переименовать / начать загрузку файла, и мы дважды обработаем файл, что может быть Плохой вещью (tm). - person Drizzt321; 01.07.2011

Вы не можете, по крайней мере, не надежно. memcached не дает никаких гарантий относительно сохранения данных — как кэш, он может удалить данные в любой момент без предупреждения. Даже если кажется, что в экземпляре memcache есть свободное место, возможно, ему придется удалить данные из-за ограничений плиты.

Если вам нужна распределенная блокировка, вам нужно искать в другом месте — memcached не подходит для этой работы. Что бы это ни стоило, MySQL имеет блокировки: http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html

person Community    schedule 30.06.2011
comment
Замок нам давно не нужен, этот момент рассматривался, и если хотя бы 1 из 3-х ключей существует, то замок не может быть получен. - person Drizzt321; 30.06.2011
comment
На практике это должно быть очень надежно, пока набор данных, который вы кэшируете, очень мал (например, несколько замков) и вы используете выделенный кеш. - person jtoberon; 01.07.2011
comment
@duskwuff относится ли это к stackoverflow.com/ вопросов/37458587/ мое главное сомнение заключается в том, что memcache.get и всегда будут возвращать значение, если оно существует, или иногда оно ничего не возвращает из-за соображений производительности, когда он не может обработать запрос достаточно быстро и т. д. Может ли он пропустить . - person Nishant; 27.05.2016

Если вы используете 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/

Надеюсь, поможет.

person Germán    schedule 17.01.2012