Lua скрипты

Тема дорожной карты · Redis

Redis встраивает интерпретатор Lua 5.1, позволяющий клиентам выполнять атомарные скрипты на сервере командой EVAL, объединяя несколько операций Redis в единую транзакционную единицу. Lua-скрипт передаётся как строка в EVAL script numkeys key [key ...] arg [arg ...], при этом ключи и аргументы доступны внутри скрипта через таблицы KEYS и ARGV. Использование redis.call('SET', KEYS[1], ARGV[1]) внутри Lua выполняет команду Redis и вызывает ошибку Lua при сбое, а redis.pcall() возвращает объекты ошибок для аккуратной обработки. Скрипты кэшируются на сервере по их SHA1-хэшу: SCRIPT LOAD предварительно загружает скрипт и возвращает его хэш, который EVALSHA затем использует для выполнения без повторной передачи исходного кода. Lua-скриптинг в Redis идеально подходит для реализации compare-and-swap, условных операций и атомарных паттернов «чтение-изменение-запись», которые нельзя выразить только транзакциями MULTI/EXEC.

Как это работает

Lua скрипты имеет два инструмента атомарности. MULTI/EXEC ставит команды в очередь; они выполняются как один блок — но нет rollback (Redis не ACID-D, изоляции тоже нет, если читаете между командами). WATCH добавляет optimistic locking — EXEC валится, если watched-ключ изменился. EVAL / EVALSHA исполняет Lua-скрипты атомарно на сервере; скрипт — одна неделимая операция. Lua — правильный инструмент для compound read+write, которые должны быть атомарными.

Когда применять

MULTI/EXEC — для "выполнить эти N команд как единицу без других команд между". WATCH + MULTI/EXEC — для compare-and-swap. Lua (EVAL) — для сложной атомарной логики (rate limiter, debounce, distributed semaphore). Всегда кешируйте SHA (EVALSHA) вместо повторной отправки тела скрипта — экономит bandwidth и парсинг.

Типичные ошибки

Ловушки Lua скрипты: расчёт, что MULTI/EXEC — транзакция в SQL-смысле (нет — без rollback); долгие Lua-скрипты блокируют однопоточный сервер (всё ждёт EXEC); не обрабатывают nil от EXEC (WATCH-конфликт — retry); Lua-код, мутирующий ключ на основе текущего значения без WATCH (race condition при разделении на команды).

Связанные понятия

Полезные ресурсы