Aerospike — Реализация блокировки пакетной операции

Aerospike предлагает блокировку на уровне строки.
(1) Можно ли использовать эту функцию для реализации мьютекса/блокировки операции с несколькими записями?
(2) Рекомендуется?

Пример реализации
 — Две определяемые пользователем функции: одна для получения блокировки, другая для ее освобождения
 – Приложение должно получить блокировку перед началом "операции"
 – Запись блокировки может иметь TTL в случае, если приложение не удается снять блокировку по истечении определенного времени.
 — Напишите для политики выполнения определяемой пользователем функции значение "ВСЕ"

-- return true if lock acquisition successful; else return false
function acquireLock(record, lockBin)
    if not aerospike:exists(record) then
        aerospike:create(record)
    end

    if record[lockBin] == 1 then
        return false
    end

    record[lockBin] = 1
    aerospike:update(record)
    return true
end

-- return true if lock release successful, else return false
function releaseLock(record, lockBin) 
    if not aerospike:exists(record) then
        return false
    end

    if not record[lockBin] == 1 then
        return false
    end

    record[lockBin] = 0
    aerospike:update(record)
    return false    
end

person Aaron    schedule 14.12.2015    source источник
comment
Изучали ли вы оптимистичные концепции, такие как сравнение и замена (CAS), или способы объединения этих записей в одну? НЕ рекомендуется использовать такие замки. Такой подход серьезно ограничит пропускную способность до нескольких обновлений в секунду (максимум).   -  person Manuel Arwed Schmidt    schedule 15.12.2015
comment
И самое главное: блокировка не будет распространяться на несколько записей, поэтому вам придется заблокировать обе записи и, следовательно, столкнуться со всеми видами взаимоблокировок. Резюме: это, вероятно, создаст больше проблем для вашего приложения, чем решит.   -  person Manuel Arwed Schmidt    schedule 15.12.2015
comment
(1) Спасибо за совет CAS. Я взгляну. (2) Эта блокировка внесет измеримую задержку в общую транзакцию. Но операция не такая интенсивная, поэтому одновременные возможности должны быть приличными. (3) Если все клиенты знают, что необходимо получить эту одну блокировку, прежде чем начинать чтение/запись в связанных наборах, потребуется только одна блокировка. С TTL любой сценарий взаимоблокировки должен быть смягчен. (4) К счастью, я смог изменить свою схему, чтобы не нуждаться в этой блокировке.   -  person Aaron    schedule 16.12.2015
comment
Рада, что вы смогли адаптироваться! Теперь я понимаю, что вы хотели реализовать единую блокировку в одной записи, что снижает риск взаимоблокировки с TTL, конечно. Впрочем, обычно в этом нет необходимости. ТБХ: Я запускаю вещи с оптимистичным параллелизмом, но создаю запись для каждой транзакции, поэтому, если что-то пошло не так, всегда есть возможность воспроизвести или вручную исправить отдельные записи в случае несоответствия. Это обычное дело, поскольку в мире NoSQL предпочтение отдается масштабу и производительности :)   -  person Manuel Arwed Schmidt    schedule 16.12.2015
comment
Предложение @ManuelArwedSchmidt хорошее. вам следует использовать операцию CAS, предлагаемую Aerospike через политику проверки генерации. UDF является излишним для этого. Кажется, у вас есть близость к UDF. Имейте в виду их накладные расходы. UDF следует использовать, если у вас есть сложная логика, которая не может быть достигнута с помощью собственного API.   -  person sunil    schedule 18.12.2015
comment
Спасибо, это очень полезно.   -  person Aaron    schedule 18.12.2015


Ответы (1)


Обобщая несколько комментариев, сделанных другими:

Хотя такая реализация возможна, она крайне не рекомендуется из-за низкой производительности. Взгляните на функцию сравнения и замены Aerospike (CAS), чтобы добиться чего-то подобного.

person Aaron    schedule 21.12.2015