Серия Redis (9): Механизм транзакций Redis

Redis

Когда дело доходит до транзакций, я считаю, что все знакомы с четырьмя ACID-характеристиками транзакций, которые часто задают во время интервью.Однако в целом мы можем думать о транзакциях в традиционных реляционных базах данных.На самом деле, Redis также предоставляет механизмы транзакций. , этот блог объяснит механизм транзакций Redis.

1. Демонстрация транзакции

Транзакции в Redis предоставляют механизм для упаковки нескольких командных запросов и одновременного и последовательного выполнения нескольких команд.

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

На следующем рисунке показан процесс выполнения транзакции Redis:

Видно, что транзакцияMULTIкоманда, затем несколько команд помещаются в транзакцию и, наконец,EXECКоманда отправляет эту транзакцию на сервер для выполнения.

2. Принцип реализации сделки

Сделка проходит следующие 3 стадии от начала до конца:

  1. бизнес начинается
  2. очередь команд
  3. выполнение транзакции

2.1 Начало транзакции

MULTIВыполнение команды знаменует собой начало транзакции.

После выполнения команды атрибут flags состояния клиента включит флаг REDIS_MULTI, указывающий, что клиент переключается из нетранзакционного состояния в транзакционное состояние.

2.2 Очередь команд

когда клиент внетранзакционное состояние, команда, отправленная этим клиентом, будет немедленно выполнена сервером:

когда клиент встатус транзакции, будет ли сервер немедленно выполнять команду, отправленную клиентом, делится на следующие две ситуации:

  1. Если команда, отправленная клиентом,MULTI,EXEC,WATCH,DISCARD1 из четырех команд, сервер немедленно выполнит эту команду.
  2. Если команда, отправленная клиентом, отличается от вышеуказанных 4 команд, сервер не будет выполнять команду немедленно, а поместит ее в очередь транзакций, а затем вернется к клиенту.QUEUEDОтветить.

Описанный выше процесс может быть представлен следующей блок-схемой:

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

затем поднимитеочередь транзакций, у каждого клиента Redis есть собственное состояние транзакции, которое хранится в атрибуте mstates состояния клиента:

Состояние транзакции содержит количество 1 очереди транзакций и 1 поставленной в очередь команды следующим образом:

Очередь транзакций представляет собой массив типа multiCmd. Каждая структура multiCmd в массиве хранит информацию о поставленной в очередь команде, например:

  1. Указатель на функцию реализации команды, такую ​​как команда GET, команда SET
  2. параметры команды
  3. количество параметров

Очередь транзакций хранит поставленные в очередь команды в порядке поступления (FIFO).

2.3 Выполнение транзакции

Когда транзакционный клиент выполняетEXECкоманда, сервер пройдет по очереди транзакций клиента и выполнит все команды, сохраненные в очереди (в порядке поступления), а затем за один раз вернуть результат выполнения команды клиенту.

3. Принцип реализации команды WATCH

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

Для лучшего понимания проведем демонстрацию Сначала мы открываем клиент 1 и выполняемWATCHКоманда следит за ключом «имя», затем запускает транзакцию:

На этом этапе не выполняйте команду EXEC, откройте клиент 2 и выполните следующую команду, чтобы изменить значение ключа «имя»:

Затем, когда клиент 1 выполняет команду EXEC, возвращается пустой ответ, поскольку значение ключа «имя» было изменено на клиенте 2:

Так,WATCHКаков принцип реализации команды? Мы анализируем его со следующих трех аспектов:

  1. Отслеживайте ключи базы данных с помощью команды WATCH
  2. Запуск механизма мониторинга
  3. Как определить, безопасна ли транзакция

3.1 Используйте команду WATCH для мониторинга ключей базы данных

Каждая база данных Redis содержит 1watched_keysDictionary, ключ этого словаря — это ключ базы данных, отслеживаемый командой WATCH, а значение словаря — это связанный список, который записывает всех клиентов, отслеживающих соответствующий ключ базы данных.

Например, если клиент 1 отслеживает ключ «имя», а клиент 2 отслеживает ключ «возраст», тоwatched_keysДанные, хранящиеся в словаре, примерно следующие:

Если клиент 3 выполняет следующееWATCHЗаказ:

Такwatched_keysДанные, хранящиеся в словаре, становятся:

3.2 Запуск механизма мониторинга

Итак, вопрос в том, что, посколькуwatched_keysВ словаре хранятся ключи, которые отслеживаются командой WATCH, так как же запускается механизм наблюдения?

Ответ: все команды, изменяющие базу данных, такие какSET,LPUSH,SADDподождите, после выполнения исправитсяwatched_keysСловарь проверяется, и если какой-либо клиент отслеживает ключ, который был только что изменен командой, то все клиенты, отслеживающие этот ключREDIS_DIRTY_CASФлаг будет включен, указывая на то, что безопасность транзакции для этого клиента была нарушена.

Возьмите приведенный выше рисунок в качестве примера, если значение ключа «имя» изменено, то клиент 1 и клиент 3REDIS_DIRTY_CASЛоготип будет включен.

3.3 Определение безопасности транзакции

Последний и очень важный шаг — когда сервер получает сообщение от клиента.EXECкоманда, сервер будет основан на том, открыт ли клиентREDIS_DIRTY_CASИдентификация используется для принятия решения о выполнении транзакции.Схема судебного решения выглядит следующим образом:

4. Пример сбоя выполнения транзакции

Сначала рассмотрим первый пример. Эта транзакция связана с тем, чтоОшибка постановки команды в очередьОтклонено сервером, все команды в транзакции не будут выполнены:

Давайте посмотрим на второй пример, когда транзакция поставлена ​​в очередь, появляетсянесуществующая команда, сервер откажется выполнять транзакцию:

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

Этот пример также показываетТранзакции Redis не поддерживают механизм отката.

5. Резюме

Транзакции Redis предоставляют механизм упаковки нескольких команд, а затем однократного и упорядоченного их выполнения.

Его принцип заключается в том, что несколько команд будут помещены в очередь транзакций, а затем выполнены в порядке «первым поступил — первым обслужен» (FIFO).

И транзакция не будет прервана в процессе выполнения, и транзакция не завершится, пока не будут выполнены все команды в очереди транзакций.

6. Ссылка

Хуан Цзяньхун «Проектирование и реализация Redis»


Примечание. Если вы считаете, что в этом блоге есть какие-либо ошибки или лучшие предложения, оставьте сообщение, я слежу и вовремя исправлю содержание блога!

Статья будет постоянно обновляться, пожалуйста, обратите внимание на общедоступный аккаунт WeChat «Shencheng Stranger», чтобы прочитать ее впервые!