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. Эти места имеют свои собственные копии данных для каждого запроса.
См. также
- модуль ngx_lua: http://wiki.nginx.org/HttpLuaModule
- спецификация проводного протокола memcached: http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt
- библиотека lua-resty-redis.
- библиотека lua-resty-mysql.
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-memcached.