Расскажите подробнее о распределенных блокировках Redis🔒

Java
Расскажите подробнее о распределенных блокировках Redis🔒

последовательность - клочья

Неделя N работы из дома,

Не знаю, скучают ли по мне клавиатура и монитор на рабочей станции автора.

Я не знаю, будет ли зола слишком серьезной и будет ли выброшена теткой-уборщицей.


Сегодня автор приносит статью о блокировках Redis.

Стучите и рисуйтеКод этой статьи, есть некоторые детали, для тех, кто не понимает блокировку Redis, вы можете взглянуть.

Если это опытный травник, выискивающий ошибки, то автору еще больше благодарности~

Не много сплетен, пошли сейчас.

Текст - Прямо к делу

Когда дело доходит до блокировки Redis, следующие три слова являются наиболее часто встречающимися словами:

  • setnx
  • redLock
  • redisson

setnx

Фактически, часто используемая команда setnx относится не только к redis.setnx key valueэта команда.

Обычно относится к паре в Redissetкоманда плюсnxиспользуемые параметры,setЭта команда в настоящее время поддерживает так много необязательных параметров:

SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]

Я конечно не буду в статье писать Апи по умолчанию.Основные параметры пока не ясны.Вы можете перейти кОфициальный сайт.

Картинка выше нарисована авторомsetnxОбщий принцип в основном основан наФункция, что ключ не существует для успешной установки, процесс A получает блокировку, и когда нет ключа для снятия блокировки, процесс B, естественно, не может получить блокировку.

Так зачем использоватьPX 30000установить таймаут?

боитсяПроцесс АЭто неразумно, замок еще не сняли,на случай, если он сломается, и напрямую забрали блокировку, чтобы никто в системе не мог получить блокировку.

Даже в этом случае не гарантируется надежность.

еслиПроцесс АНеразумно управлять ресурсами в замкеПревышено время ожидания, установленное автором, то это приведет кдругой процесс получает блокировку,ЖдатьПроцесс АВернувшись, я удалил блокировки других процессов, как показано на рисунке:

Та же самая картина только что,T5Время было изменено на время ожидания блокировки, которое было выпущено Redis.

Процесс БсуществуетT6Рад получить замок менее чем через некоторое время,Процесс АОперация завершена, вернуть одинdel, блокировка снимается.

когдаПроцесс БКогда операция завершена и блокировка снята (момент T8 на рисунке):

Неплохо, если ты не можешь найти замок, на всякий случай.T7есть моментпроцесс СПриходите и заблокируйте успешно, затемПроцесс Бставитьпроцесс СЗамок разблокирован.
И так далее,процесс Сможет освободитьпроцесс Dзамок,процесс D.... (матрешки нет), конкретные последствия неизвестны.

Итак, используяsetnxКогда ключ является основной функцией, ноvalueНе может бездействовать, вы можете установитьуникальный идентификатор клиентаили сUUIDэто случайное число.

При разблокировке сначала получите значение, чтобы определить, является ли это блокировкой, добавленной текущим процессом, а затем удалите ее.Поддельный код:

String uuid = xxxx;
// 伪代码,具体实现看项目中用的连接工具
// 有的提供的方法名为set 有的叫setIfAbsent
set Test uuid NX PX 3000
try{
// biz handle....
} finally {
    // unlock
    if(uuid.equals(redisTool.get('Test')){
        redisTool.del('Test');
    }
}

На этот раз все стабильно?

Напротив, на этот раз проблема более очевидна, в блоке finally,get и del не являются атомарными операциями, есть еще проблемы с безопасностью процесса.

Почему так много вопросов?

Во-первых, выяснить, где есть слабые места, чтобы лучше совершенствоваться.

Второй пункт, собственно, последний кусок кода выше, там ещеМногие компании используютиз.

Парадокс больших и малых проектов: Крупные компании реализуют спецификации, но маленькие компании и маленькие проекты не строги, но параллелизм невысок, а вероятность проблем так же низка, как и у крупных компаний. -- Лу Синь

Тогда одним из правильных жестов для снятия блокировки является использованиеluaскрипт через редисeval/evalshaкоманда для запуска:

-- lua删除锁:
-- KEYS和ARGV分别是以集合方式传入的参数,对应上文的Test和uuid。
-- 如果对应的value等于传入的uuid。
if redis.call('get', KEYS[1]) == ARGV[1] 
    then 
	-- 执行删除操作
        return redis.call('del', KEYS[1]) 
    else 
	-- 不成功,返回0
        return 0 
end

пройти черезluaПричина, по которой скрипт может гарантировать атомарность, проста:

даже если тыluaНапишите в нем цветы, а исполнение тоже команда(eval/evalsha) выполнить, команда не выполняется, и другие клиенты ее не видят.

Итак, поскольку это так хлопотно, есть ли лучший инструмент? собирался сказатьredisson.


вводитьredissonРанее автор кратко объяснил, почему нынешняяsetnxПо умолчаниюsetпринести командуnxпараметры, вместо того, чтобы прямо сказать даsetnxэта команда.

потому что версия Redis находится в2.6.12Раньше set не поддерживал параметр nx.Если вы хотите завершить блокировку, вам нужны две команды:

1. setnx Test uuid
2. expire Test 30

То есть ввод Ключа и установка срока действия это два отдельных шага, которые теоретически появятся1Сразу после выполнения программа зависает, и атомарность не может быть гарантирована.

Но уже как2013 год, то есть 7 лет назад был выпущен Redis2.6.12версию и официальный сайт (установить командную страницу), также заявлял ранее, что «SETNX, SETEX, PSETEX могут быть объявлены устаревшими иудалить навсегда".

Автор когда-то читал статью большого парня, в которой есть небольшая рутинная беседа для руководства новичками.Конкретные слова забыты, а общий смысл таков:

Когда дело доходит до блокировок Redis, вы можете начать с setnx, а затем постепенно вводить параметры команды set, которые могут отражать ваши знания.

Если вы прочитали эту статью и изучили эту процедуру, как автор этой статьи, я хотел бы добавить напоминание:

Пожалуйста, обратите внимание на ваши рабочие годы! Сначала ответьте на приказ, который официальный сайт указывает на то, что он будет заброшен, а затем выяснитеустановить команду«Новая функция» семилетней давности, если кто-то только что закончил школу, интервьюер подумает, что он прошел.

Вы назначите интервьюера, интервьюер настроит вас. -- ВТ Возкишор

redisson

РедиссонОдин из клиентов Java Redis, который предоставляет некоторые API для облегчения работы Redis.

Но клиент redisson немного мощнее Автор перехватил только часть картинки на официальном сайте:

Можно сказать, что этот список функций слишком велик, вы видели некоторые из них?JUCИмя класса под пакетом, redisson помог нам сделать распределённую версию, напримерAtomicLong, использовать напрямуюRedissonAtomicLongВот и все, вам даже не нужно запоминать имя класса, это очень удобно.

Замки — это только верхушка айсберга, и с егоwikiКак вы можете видеть на странице, поддерживаются все режимы, такие как master-slave, sentinel и cluster.Конечно, режим с одним узлом определенно поддерживается.

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

Исходный код реализации обычной блокировки Redisson в основномRedissonLockТем из вас, кто не видел исходный код этого класса, стоит взглянуть.

в исходном кодеблокировка/разблокировка блокировкиоперация используетсяluaСкрипт завершен, инкапсуляция очень идеальна, и его можно использовать из коробки.

Вот небольшая деталь, используйте замокsetnxможет быть достигнуто также с помощьюluaСкрипт лишний? Автор такжеочень строгийЯ некоторое время думал об этом: как такая мощная штука может писать ненужный код?

На самом деле автор присмотрелся.Скрипт Lua для блокировки и разблокировки очень всеобъемлющий, в том числеБлокировка повторного входа, этот момент можно назвать очень продуманным, и я также написал код для его проверки:

это похоже на ддкReentrantLockТакая же шелковистая гладкость, поэтому реализация redisson была настолько идеальной, что такое redLock?

RedLock

redLockКитайский - это дословный перевод, он называетсякрасный замок.

Red lock — это не инструмент, а распределённая блокировка, официально предложенная Redis.алгоритм.

Просто в только что представленном Redisson реализована версия замка REDLOCK. то естьgetLockметод иgetRedLockметод.

Автор примерно нарисовал картину понимания красного замка:

Если вы не знакомы с развертываниями высокой доступности Redis, это нормально. Хотя для алгоритма redLock требуется несколько экземпляров, эти экземпляры развертываются независимо, и отношения «ведущий-ведомый» отсутствуют.

Автор RedLock указал, что причина использования Independent заключается в том, чтобы избежать потери блокировок, вызванной асинхронной репликацией redis, например: если мастер-узел не приходит, аПросто введите эти данные вПередайте его подчиненному узлу и повесьте трубку.

Кто-то думает, что все большие парни — гангстеры, каждый день думающие о экстремальных ситуациях? фактическиВысокая доступностьНу и бой99.999...%Количество цифр после запятой.

Возвращаясь к простой картинке выше, алгоритм красной блокировки считает, что до тех пор, пока (N/2) + 1 узел успешно заблокирован, блокировка считается полученной, и все экземпляры разблокируются при разблокировке. Процесс:

  1. Последовательно запрашивать блокировки с пяти узлов
  2. согласно определеннымсверхурочное времясделать вывод, следует ли пропустить узел
  3. Три узла успешно заблокированы и затраченное время меньше срока действия блокировки
  4. Подтвердите, что блокировка прошла успешно

То есть, предполагая блокировку30 секундСрок истек, для блокировки трех узлов потребовалась 31 секунда, и, естественно, блокировка не удалась.

Это просто пример, на самом деле не стоит ждать так долго для каждой ноды, как написано на официальном сайте, предполагая срок действия 10второй, то время ожидания операции одного экземпляра Redis должно составлять от 5 до 50миллисекунда(обратите внимание на единицу времени)

Или предположим, что мы установили период действия на 30 секунд, а время ожидания двух узлов redis на рисунке истекло.
Затем узел, который успешно блокируетсяОбщая стоимость3 секунды, так заблокированоФактический срок действиясоставляет менее 27 секунд.

То есть вычитаются 3 секунды трех успешных экземпляров блокировки, и вычитается общее время ожидания тайм-аута экземпляра redis.

Увидев это, у вас могут возникнуть некоторые сомнения по поводу этого алгоритма, значит, вы не одиноки.

Оглянитесь на официальный сайт Redis о красном замкеописывать

Прямо внизу этой страницы описания вы можете увидеть знаменитый красный замок.фея бойсобытие.

А именно Martin Kleppmann и дискуссия antirez о redLock, один из которых является высококвалифицированным распределенным архитектором, а другой — отцом redis.

Официальные повешенные люди, самые смертоносные.

Шучу, если вопрос может быть официально связан с официальным сайтом, он должен быть ценным.

Так что если вы хотите использовать красный замок в проекте, помимо введения красного замка, вы можете прочитать еще две статьи, а именно:

  1. Сообщение с вопросом от Мартина Клеппманна
  2. контратака антиреза

Суммировать

Прочитав так много, я не могу гарантировать, узнал ли я, как это реализовать.100% стабильный.

Программа такая, абсолютной стабильности нет, так что делайте хорошоискусственная компенсацияСсылка тоже важная ссылка, в конце концов:

Технологии недостаточно, она искусственно собрана~