Перейти к содержанию

memcached: Lua клиент для memcached для nginx-module-lua на основе API cosocket

Установка

Если вы еще не настроили подписку на репозиторий RPM, подпишитесь. Затем вы можете продолжить с следующими шагами.

CentOS/RHEL 7 или Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-memcached

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-memcached

Чтобы использовать эту библиотеку Lua с NGINX, убедитесь, что nginx-module-lua установлен.

Этот документ описывает lua-resty-memcached v0.18, выпущенный 7 июня 2026 года.


Эта библиотека Lua является клиентом для memcached для модуля ngx_lua nginx:

http://wiki.nginx.org/HttpLuaModule

Эта библиотека Lua использует API cosocket модуля ngx_lua, который обеспечивает 100% неблокирующее поведение.

Обратите внимание, что требуется как минимум ngx_lua 0.5.0rc29 или OpenResty 1.0.15.7.

Синопсис

    server {
        location /test {
            content_by_lua '
                local memcached = require "resty.memcached"
                local memc, err = memcached:new()
                if not memc then
                    ngx.say("не удалось создать memc: ", err)
                    return
                end

                memc:set_timeout(1000) -- 1 секунда

                -- или подключиться к файлу сокета unix,
                -- на который слушает сервер memcached:
                --     local ok, err = memc:connect("unix:/path/to/memc.sock")

                local ok, err = memc:connect("127.0.0.1", 11211)
                if not ok then
                    ngx.say("не удалось подключиться: ", err)
                    return
                end

                local ok, err = memc:flush_all()
                if not ok then
                    ngx.say("не удалось очистить все: ", err)
                    return
                end

                local ok, err = memc:set("dog", 32)
                if not ok then
                    ngx.say("не удалось установить dog: ", err)
                    return
                end

                local res, flags, err = memc:get("dog")
                if err then
                    ngx.say("не удалось получить dog: ", err)
                    return
                end

                if not res then
                    ngx.say("dog не найден")
                    return
                end

                ngx.say("dog: ", res)

                -- поместить в пул соединений размером 100,
                -- с максимальным временем простоя 10 секунд
                local ok, err = memc:set_keepalive(10000, 100)
                if not ok then
                    ngx.say("не удалось установить keepalive: ", err)
                    return
                end

                -- или просто закрыть соединение сразу:
                -- local ok, err = memc:close()
                -- if not ok then
                --     ngx.say("не удалось закрыть: ", err)
                --     return
                -- end
            ';
        }
    }

Методы

Аргумент key, предоставленный в следующих методах, будет автоматически экранирован в соответствии с правилами экранирования URI перед отправкой на сервер memcached.

new

синтаксис: memc, err = memcached:new(opts?)

Создает объект memcached. В случае неудачи возвращает nil и строку, описывающую ошибку.

Принимает необязательный аргумент opts в виде таблицы. Поддерживаются следующие опции:

  • key_transform

    массив таблиц, содержащий две функции для экранирования и декодирования ключей memcached соответственно. По умолчанию ключи memcached будут экранированы и декодированы как компоненты URI, то есть

    memached:new{
        key_transform = { ngx.escape_uri, ngx.unescape_uri }
    }

connect

синтаксис: ok, err = memc:connect(host, port)

синтаксис: ok, err = memc:connect("unix:/path/to/unix.sock")

Пытается подключиться к удаленному хосту и порту, на которых слушает сервер memcached, или к локальному файлу сокета unix, на который слушит сервер memcached.

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

sslhandshake

синтаксис: session, err = memc:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)

Выполняет SSL/TLS рукопожатие на текущем установленном соединении. См. API tcpsock.sslhandshake от OpenResty для получения дополнительной информации.

set

синтаксис: ok, err = memc:set(key, value, exptime, flags)

Вставляет запись в memcached без условий. Если ключ уже существует, он будет переопределен.

Аргумент value также может быть таблицей Lua, содержащей несколько строк Lua, которые должны быть объединены в одно целое (без разделителей). Например,

    memc:set("dog", {"a ", {"kind of"}, " animal"})

функционально эквивалентно

    memc:set("dog", "a kind of animal")

Параметр exptime является необязательным и по умолчанию равен 0 (что означает, что никогда не истекает). Время истечения указано в секундах.

Параметр flags является необязательным и по умолчанию равен 0.

set_timeout

синтаксис: ok, err = memc:set_timeout(timeout)

Устанавливает защиту по времени (в мс) для последующих операций, включая метод connect.

Возвращает 1 при успешном выполнении и nil плюс строку, описывающую ошибку в противном случае.

set_timeouts

синтаксис: ok, err = memc:set_timeouts(connect_timeout, send_timeout, read_timeout)

Устанавливает таймауты (в мс) для операций подключения, отправки и чтения соответственно.

Возвращает 1 при успешном выполнении и nil плюс строку, описывающую ошибку в противном случае.

set_keepalive

синтаксис: ok, err = memc:set_keepalive(max_idle_timeout, pool_size)

Сразу помещает текущее соединение memcached в пул соединений ngx_lua.

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

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

Вызывайте этот метод только в том месте, где вы бы вызвали метод close. Вызов этого метода немедленно переведет текущий объект memcached в состояние closed. Любые последующие операции, кроме connect(), на текущем объекте вернут ошибку closed.

get_reused_times

синтаксис: times, err = memc:get_reused_times()

Этот метод возвращает количество (успешно) повторно использованных раз для текущего соединения. В случае ошибки он возвращает nil и строку, описывающую ошибку.

Если текущее соединение не поступает из встроенного пула соединений, то этот метод всегда возвращает 0, то есть соединение никогда не было повторно использовано (пока). Если соединение поступает из пула соединений, то возвращаемое значение всегда будет ненулевым. Таким образом, этот метод также можно использовать для определения, поступает ли текущее соединение из пула.

close

синтаксис: ok, err = memc:close()

Закрывает текущее соединение memcached и возвращает статус.

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

add

синтаксис: ok, err = memc:add(key, value, exptime, flags)

Вставляет запись в memcached, если и только если ключ не существует.

Аргумент value также может быть таблицей Lua, содержащей несколько строк Lua, которые должны быть объединены в одно целое (без разделителей). Например,

    memc:add("dog", {"a ", {"kind of"}, " animal"})

функционально эквивалентно

    memc:add("dog", "a kind of animal")

Параметр exptime является необязательным и по умолчанию равен 0 (что означает, что никогда не истекает). Время истечения указано в секундах.

Параметр flags является необязательным, по умолчанию равен 0.

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

replace

синтаксис: ok, err = memc:replace(key, value, exptime, flags)

Вставляет запись в memcached, если и только если ключ существует.

Аргумент value также может быть таблицей Lua, содержащей несколько строк Lua, которые должны быть объединены в одно целое (без разделителей). Например,

    memc:replace("dog", {"a ", {"kind of"}, " animal"})

функционально эквивалентно

    memc:replace("dog", "a kind of animal")

Параметр exptime является необязательным и по умолчанию равен 0 (что означает, что никогда не истекает). Время истечения указано в секундах.

Параметр flags является необязательным, по умолчанию равен 0.

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

append

синтаксис: ok, err = memc:append(key, value, exptime, flags)

Добавляет значение к записи с тем же ключом, которая уже существует в memcached.

Аргумент value также может быть таблицей Lua, содержащей несколько строк Lua, которые должны быть объединены в одно целое (без разделителей). Например,

    memc:append("dog", {"a ", {"kind of"}, " animal"})

функционально эквивалентно

    memc:append("dog", "a kind of animal")

Параметр exptime является необязательным и по умолчанию равен 0 (что означает, что никогда не истекает). Время истечения указано в секундах.

Параметр flags является необязательным, по умолчанию равен 0.

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

prepend

синтаксис: ok, err = memc:prepend(key, value, exptime, flags)

Добавляет значение к записи с тем же ключом, которая уже существует в memcached.

Аргумент value также может быть таблицей Lua, содержащей несколько строк Lua, которые должны быть объединены в одно целое (без разделителей). Например,

    memc:prepend("dog", {"a ", {"kind of"}, " animal"})

функционально эквивалентно

    memc:prepend("dog", "a kind of animal")

Параметр exptime является необязательным и по умолчанию равен 0 (что означает, что никогда не истекает). Время истечения указано в секундах.

Параметр flags является необязательным, по умолчанию равен 0.

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

get

синтаксис: value, flags, err = memc:get(key) синтаксис: results, err = memc:get(keys)

Получает одну запись или несколько записей на сервере memcached через один ключ или таблицу ключей.

Сначала обсудим случай, когда ключ — это одна строка.

Значение ключа и связанное значение флагов будут возвращены, если запись найдена и ошибки не произошло.

В случае ошибок значения nil будут возвращены для value и flags, а также будет возвращено третье (строковое) значение для описания ошибки.

Если запись не найдена, то будут возвращены три значения nil.

Теперь обсудим случай, когда предоставляется таблица Lua с несколькими ключами.

В этом случае всегда будет возвращаться таблица Lua, содержащая пары ключ-результат в случае успеха. Каждое значение, соответствующее каждому ключу в таблице, также является таблицей, содержащей два значения: значение ключа и флаги ключа. Если ключ не существует, то в таблице results не будет соответствующих записей.

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

gets

синтаксис: value, flags, cas_unique, err = memc:gets(key)

синтаксис: results, err = memc:gets(keys)

Так же, как и метод get, но также будет возвращено уникальное значение CAS, связанное с записью, в дополнение к значению ключа и флагам.

Этот метод обычно используется вместе с методом cas.

cas

синтаксис: ok, err = memc:cas(key, value, cas_unique, exptime?, flags?)

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

Аргумент cas_unique можно получить из метода gets.

touch

синтаксис: ok, err = memc:touch(key, exptime)

Обновляет время истечения существующего ключа.

Возвращает 1 при успехе или nil с описанием ошибки в противном случае.

Этот метод был впервые представлен в релизе v0.11.

flush_all

синтаксис: ok, err = memc:flush_all(time?)

Немедленно очищает (или аннулирует) все существующие записи на сервере memcached (по умолчанию) или после времени истечения, указанного аргументом time (в секундах).

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

delete

синтаксис: ok, err = memc:delete(key)

Немедленно удаляет ключ из memcached.

Ключ, который необходимо удалить, должен уже существовать в memcached.

В случае успеха возвращает 1. В случае ошибок возвращает nil с описанием ошибки.

incr

синтаксис: new_value, err = memc:incr(key, delta)

Увеличивает значение указанного ключа на целочисленное значение, указанное в аргументе delta.

Возвращает новое значение после увеличения в случае успеха и nil с описанием ошибки в случае неудачи.

decr

синтаксис: new_value, err = memc:decr(key, value)

Уменьшает значение указанного ключа на целочисленное значение, указанное в аргументе delta.

Возвращает новое значение после уменьшения в случае успеха и nil с описанием ошибки в случае неудачи.

stats

синтаксис: lines, err = memc:stats(args?)

Возвращает информацию о статистике сервера memcached с необязательным аргументом args.

В случае успеха этот метод возвращает таблицу lua, содержащую все строки вывода; в случае неудачи он возвращает nil с описанием ошибки.

Если аргумент args опущен, возвращается общая статистика сервера. Возможные значения аргумента args включают items, sizes, slabs и другие.

quit

синтаксис: ok, err = memc:quit()

Сообщает серверу закрыть текущее соединение memcached.

Возвращает 1 в случае успеха и nil в противном случае. В случае неудачи также будет возвращено другое строковое значение для описания ошибки.

В общем, вы можете просто напрямую вызвать метод close, чтобы достичь того же эффекта.

verbosity

синтаксис: ok, err = memc:verbosity(level)

Устанавливает уровень подробности, используемый сервером memcached. Аргумент level должен быть задан только целыми числами.

Возвращает 1 в случае успеха и nil в противном случае. В случае неудачи также будет возвращено другое строковое значение для описания ошибки.

init_pipeline

синтаксис: err = memc:init_pipeline(n?)

Включает режим конвейеризации Memcache. Все последующие вызовы методов команд Memcache будут автоматически буферизоваться и отправляться на сервер за один раз, когда будет вызван метод commit_pipeline, или будут отменены вызовом метода cancel_pipeline.

Необязательный параметр n — это размер буфера таблиц. Значение по умолчанию — 4.

commit_pipeline

синтаксис: results, err = memc:commit_pipeline()

Выходит из режима конвейеризации, подтверждая все кэшированные запросы Memcache на удаленный сервер за один раз. Все ответы на эти запросы будут автоматически собраны и возвращены так, как если бы это был большой многообъемный ответ на самом высоком уровне.

Этот метод успешно возвращает таблицу lua. В случае неудачи возвращает строку lua, описывающую ошибку.

cancel_pipeline

синтаксис: memc:cancel_pipeline()

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

Метод ничего не возвращает. Всегда выполняется успешно.

Автоматическая регистрация ошибок

По умолчанию подлежащий модуль ngx_lua выполняет регистрацию ошибок, когда происходят ошибки сокета. Если вы уже выполняете правильную обработку ошибок в своем коде Lua, рекомендуется отключить эту автоматическую регистрацию ошибок, отключив директиву lua_socket_log_errors модуля ngx_lua, то есть,

    lua_socket_log_errors off;

Ограничения

  • Эта библиотека не может использоваться в контекстах кода, таких как set_by_lua*, log_by_lua* и header_filter_by_lua*, где API cosocket ngx_lua недоступен.
  • Экземпляр объекта resty.memcached не может храниться в переменной Lua на уровне модуля Lua, потому что он будет разделяться всеми параллельными запросами, обрабатываемыми одним и тем же рабочим процессом nginx (см. http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker) и приведет к плохим условиям гонки, когда параллельные запросы пытаются использовать один и тот же экземпляр resty.memcached. Вы всегда должны инициировать объекты resty.memcached в локальных переменных функции или в таблице ngx.ctx. Эти места имеют свои собственные копии данных для каждого запроса.

См. также

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-memcached.