Привет,ядаобезьяна Ява。
Redis и Lua, два общих золотых партнера в реальной разработке, часто появляются в технических интервью. Итак, может ли Redis гарантировать атомарность при выполнении Lua? Давайте поговорим сегодня.
Прежде чем ответить на вопрос, похоже, нам необходимо по-новому понять понятие «атомарности». Поэтому первое, что нам нужно проанализировать, — это понятие атомарности.
Атомарность реляционных баз данных
Вообще говоря, атомарность, о которой мы говорим, относится к атомарности реляционной базы данных RDBMS (например, MySQL), которая является атрибутом атомарности в ACID (атомарность, согласованность, изоляция, долговечность).
изамарность в ACID относится к да: дела изиметь операции либо все изучают успешно, либо все терпят неудачу и откатываются назад.
Вот реальный пример банковского перевода, объясняющий атомарность: Счет А переводит 100 юаней на счет Б. Атомарность означает, что когда счет А вычитает 100 юаней, счет Б должен увеличиться на 100 юаней. Если счет А уменьшается на 100 юаней, счет Б. Если увеличения на 100 юаней нет, операция не является атомарной и ее необходимо откатить, чтобы добавить обратно 100 юаней, уменьшенные на счет А. Код Java реализован следующим образом:
атомарность Lua
Если вы хотите узнать атомарность Lua, вы должны сначала понять, что такое Lua. Следующая картинка взята из официального описания Lua:
Lua — мощный, эффективный, легкий, встраиваемый язык сценариев. Он поддерживает процедурное программирование, объектно-ориентированное программирование, функциональное программирование, программирование, управляемое данными, и описание данных. Lua сочетает в себе простой процедурный синтаксис с мощными структурами описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua является динамически типизированным, работает путем интерпретации байт-кода с использованием виртуальной машины на основе регистров и обеспечивает автоматическое управление памятью и инкрементную сборку мусора, что делает его идеальным для настройки, написания сценариев и быстрого прототипирования.
Lua сам по себе не обеспечивает прямой поддержки атомарности. Это просто язык сценариев, который обычно встраивается в другие хост-программы для запуска, такие как Redis.
В Redis атомарность выполнения сценариев Lua означает, что весь сценарий Lua не будет прерываться командами других клиентов во время выполнения.
Чтобы лучше понять атомарность Redis, выполняющего Lua, вот пример трех команд, которые необходимо выполнить в сценарии Lua: `SET key1 value1`, `INCRBY key2 value2` и `SET key3 value3`:
В приведенном выше примере весь luaScript Строковый скрипт в целом изучается и не прерывается другими делами, что является атомарной операцией.
Хорошо, давайте подытожим концептуальные различия между атомарностью ACID и атомарностью Redis, выполняющего сценарии Lua:
существуют. Анализируя концепцию атомарности, мы можем обнаружить, что «амарность» на самом деле является характеристикой дадела, поэтому давайте проанализируем ее дальше. Редисиздела – это само собой разумеющееся. Изображение ниже да Официальное описание делаиз резюме Redis:
Документ выглядит очень длинным, но его можно резюмировать одним предложением: Redis делапозволятьосуществлятьпартия Заказ,проходитьосуществлять MULTIЗаказвключатьдела,осуществлять EXECЗаказ Заканчиватьдела,WATCH и DISCARD Вместе с деломиспользовать это обеспечивает CAS(check-and-set) Оптимистичный запорный механизм. СМОТРЕТЬ для мониторинга Ключ, если его контролировать Если какой-либо из Кейиметь изменится, дела будут прерваны (дела пассивно закрыты), а DISCARD Используется для активного прекращения дел.
команда MULTI/EXEC
Используйте пример, чтобы понять MULTI/EXEC:
проходитьосуществлятьиз Результаты можно увидеть:Redisизделадак Команда MULTI позволяет Команда EXEC завершается. В течение этого периода все команды сначала попадают в очередь и только выполняются. При выполнении команды EXEC все команды в очереди будут выполняться последовательно, и будет возвращен массив всех результатов выполнения команд, включая информацию об ошибках выполнения команд.
Следует отметить, что: в EXEC После изучения, даже если очередь дел иметь Заказосуществлять не удалась, другие Заказы в очереди будут обработаны, Redis Выполнение этих команд не будет остановлено.
DISCARD и WATCH Слишком Redis Используется в делаиз двух заказов, они связаны с MULTI и EXEC Вместе они обеспечивают более сложный механизм обработки.
команда СМОТРЕТЬ
команда СМОТРЕТЬдля Диптихиодин или несколько Key,еслисуществоватьосуществлятьдела во время этих Любой ключ в ключе Если значение будет изменено другим делом, все текущие дела будут прерваны. (Примечание: ниже 6.0.9 из Redis версия, срок действия ключа не прерывается (дела)
Пример ниже: дела1 watch key1 ключ2, измененный во время дела2существоватьдела1осуществлять key2 = 10,когдадела1осуществляют При выполнении команды exec, поскольку смотреть мониторы ключ2 был изменен другими делами (дела2) (значение=10) , Таким образом, дела1 отменяются, а все изаметь Заказ в очереди дел очищаются, т.е. `set key1 value1` и `incrby key 2`два Заказ Ни одиносуществлять,key2из значение по-прежнему равно 10;
дела1 | дела2 |
---|---|
watch key1 key2 | |
multi | |
set key1 value1 | |
incrby key2 2 | set key2 10 |
exec | |
ключи * // Только ключ2=10 | ключи * // Только ключ2=10 |
Команда ОТМЕНИТЬ
Команда ОТМЕНИТЬдля прерываниядела。
В следующем примере выполните После DISCARD Заказа текущие дела прекращаются, поэтому изучите EXEC «ERR» будет сообщено, когда EXEC without МУЛЬТИ" ошибка.
деласерединаизError
В делах есть два основных типа ошибок:
делаоткат
Redis не поддерживает откат.Официальное описание следующее:
Redis Откат дела не поддерживается, поскольку поддержка отката приведет к Redis Простота и производительность имеют большое значение.
Официальное описание краткое и лаконичное. На самом деле, вы можете понять его, если вдумаетесь: «Редис». да "REmote DIctionary Server" Аббревиатура, переводится как «удаленная словарная служба», первоначальная цель разработки изда заключалась в кэшировании, быстром и эффективном обеспечении. и понял ACIDделаиз Друзья должны быть в состоянии понятьделаоткатизсложность,поэтому,Кажется разумным, что Redis не поддерживает откат дел.
В этом плане мы тоже правы Redisдела сделать резюме: Redisиздела от MULTI/EXEC Две команды выполнены: WATCH/DISCARD. Два благословения Заказиз, Дават Redisдела обеспечивает CAS Оптимистичный запорный механизм. Редис дела не поддерживает откат, это и реляционная база данных (например, MySQL) издела (ACID) да это не то же самое из.
Завершен анализ атомарности После этих теоретических знаний о делах Redis нам нужно попрактиковаться и увидеть Redisда Как выполнить Luaиз。
Обычно Redis выполняет LuaОбычно используетсяизметодиметь 2 типа:
Письмо При написании Lua-скриптов необходимо обращать внимание на различие redis.call() и redis.pcall() два Заказизиспользовать。
EVAL
грамматика:
EVAL script numkeys [key [key ...]] [arg [arg ...]]
Синтаксис EVAL очень прост, EVAL script numkeys да Обязательное поле, [ключ [key ...]] [arg [arg ...]]да необязательно.
На следующих снимках экрана показано, что ключ не передан, а ключ передан. 1 ключ и 2 key 3 сценария:
Пример ниже показывает [key [key ...]] [arg [arg ...]] и ошибку сообщения об ошибке numkeys из сценария:
redis.call()
redis.call() используется для выполнения Redisиз Заказ。когда Заказосуществлять Когда возникает ошибка,Заблокирую весь скрипт изучаю,И верните сообщение об ошибке клиенту Дават.
Следующий пример: если выполнение `INCRBY key2 1/0` завершается неудачей, будет выдано исключение и последующий процесс будет заблокирован, то есть `SET key3 value3` не будет выполнен.
Примеры выполнения собственных команд Redis:
# Redis Lua callEVAL "redis.call('SET', 'key1', 'value1'); redis.call('INCRBY', 'key2', 1/0); redis.call('SET', 'key3', 'value3')" 0
Пример использования платформы Jedis для выполнения Lua выглядит следующим образом:
Проверять Каждое значение ключа после Luaосуществлять, скриншот следующий:
redis.pcall()
redis.pcall() такжеиспользуется для выполнения Redisиз Заказ。когда Заказосуществлять Когда возникает ошибка,Не блокирует скрипты изосуществовать,И да внутренне ловит ошибку,И продолжаем изучать последующие из Заказ.
Следующий пример: если выполнение INCRBY key2 1/0 завершается неудачей, исключение не создается, и последующий процесс продолжает выполняться, то есть также выполняется `SET key3 value3`.
Пример выполнения собственной команды Redis:
# Redis Lua pcallEVAL "redis.pcall('SET', 'key1', 'value1'); redis.pcall('INCRBY', 'key2', 1/0); redis.pcall('SET', 'key3', 'value3')" 0
Выполните пример Lua с использованием платформы Jedis:
для Луа redis.call() и redis.pcall() О том, как выбирать, нужно судить, исходя из реального бизнеса. Стандарт да: когда. Когда в сценарии Lua возникает определенная ошибка, нужно ли блокировать последующую ошибку?
Redisдатипичныйиз C/S(Client/Server) Модель, как показано ниже:
здесь с Автономное развертывание Redis — это пример, объясняющий, как обеспечить атомарность. Когда клиент отправляет сообщение серверу с Lua Когда скрипт будет запрошен, Redis Сценарий Lua рассматривается как единое целое. Скрипты Lua загружаются в кэш скриптов, потому что Чтение и запись Redis Заказ однопоточной операции, поэтому сценарий Lua существует для чтения и записи. Сервер Redis можно просто представить в виде следующего рисунка. Скрипты Lua будут помещены в очередь в том порядке, в котором они были введены, а затем последовательно прочитаны и записаны, что обеспечивает атомарность:
Нужно объяснить: Redis иметь 3 разных метода развертывания, разные методы развертывания, гарантии атомарности тоже разные.
В интервью: может ли Redis гарантировать атомарность при выполнении сценариев Lua? Как ответить на этот вопрос?
теперь это Redisдела может гарантировать атомарность, зачем она еще нужна? А как насчет Lua-скриптов?
При написании скрипта Redis Lua при написании Luaиз необходимо обратить внимание на следующие моменты:
Scripting with Lua:https://redis.io/docs/interact/programmability/eval-intro/
Atomicity with Lua:https://developer.redis.com/develop/java/spring/rate-limiting/fixed-window/reactive-lua/
Redis Transactions:https://redis.io/docs/interact/transactions/
The Programming Language Lua:https://www.lua.org/
наконец,Я даю вам девиз брата Юя: «Только инвестируя в себя, вы можете получить величайшее богатство».из-за уровняиметьпредел,если при хранении статьи имеются недостатки и ошибки,Критика и поправки приветствуются. если вы считаете, что статья вам полезна иметь,добро пожаловатьсосредоточиться на,Нравиться,Вперед Давать больше из друзей.