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.17, выпущенную 19 января 2023 года.
Эта библиотека 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("failed to instantiate memc: ", err)
return
end
memc:set_timeout(1000) -- 1 sec
-- или подключитесь к файлу сокета 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("failed to connect: ", err)
return
end
local ok, err = memc:flush_all()
if not ok then
ngx.say("failed to flush all: ", err)
return
end
local ok, err = memc:set("dog", 32)
if not ok then
ngx.say("failed to set dog: ", err)
return
end
local res, flags, err = memc:get("dog")
if err then
ngx.say("failed to get dog: ", err)
return
end
if not res then
ngx.say("dog not found")
return
end
ngx.say("dog: ", res)
-- поместите его в пул соединений размером 100,
-- с максимальным временем простоя 10 секунд
local ok, err = memc:set_keepalive(10000, 100)
if not ok then
ngx.say("cannot set keepalive: ", err)
return
end
-- или просто закройте соединение сразу:
-- local ok, err = memc:close()
-- if not ok then
-- ngx.say("failed to close: ", err)
-- return
-- end
';
}
}
Методы
Аргумент key, предоставленный в следующих методах, будет автоматически экранирован в соответствии с правилами экранирования URI перед отправкой на сервер memcached.
new
syntax: memc, err = memcached:new(opts?)
Создает объект memcached. В случае неудачи возвращает nil и строку, описывающую ошибку.
Принимает необязательный аргумент opts в виде таблицы. Поддерживаются следующие параметры:
-
key_transformмассив таблиц, содержащий две функции для экранирования и декодирования ключей memcached соответственно. По умолчанию ключи memcached будут экранированы и декодированы как компоненты URI, то есть
memached:new{
key_transform = { ngx.escape_uri, ngx.unescape_uri }
}
connect
syntax: ok, err = memc:connect(host, port)
syntax: ok, err = memc:connect("unix:/path/to/unix.sock")
Пытается подключиться к удаленному хосту и порту, на которых прослушивается сервер memcached, или к локальному файлу сокета unix, который прослушивается сервером memcached.
Перед тем как фактически разрешить имя хоста и подключиться к удаленному бэкенду, этот метод всегда будет искать в пуле соединений подходящие неактивные соединения, созданные предыдущими вызовами этого метода.
sslhandshake
syntax: session, err = memc:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)
Выполняет SSL/TLS рукопожатие на текущем установленном соединении. См. API tcpsock.sslhandshake от OpenResty для получения дополнительных сведений.
set
syntax: 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
syntax: ok, err = memc:set_timeout(timeout)
Устанавливает защиту по времени ожидания (в мс) для последующих операций, включая метод connect.
Возвращает 1 при успешном выполнении и nil плюс строку, описывающую ошибку в противном случае.
set_timeouts
syntax: ok, err = memc:set_timeouts(connect_timeout, send_timeout, read_timeout)
Устанавливает тайм-ауты (в мс) для операций подключения, отправки и чтения соответственно.
Возвращает 1 при успешном выполнении и nil плюс строку, описывающую ошибку в противном случае.
set_keepalive
syntax: ok, err = memc:set_keepalive(max_idle_timeout, pool_size)
Сразу помещает текущее соединение memcached в пул соединений ngx_lua.
Вы можете указать максимальное время простоя (в мс), когда соединение находится в пуле, и максимальный размер пула для каждого рабочего процесса nginx.
В случае успеха возвращает 1. В случае ошибок возвращает nil с строкой, описывающей ошибку.
Вызывайте этот метод только в том месте, где вы бы вызвали метод close. Вызов этого метода немедленно переведет текущий объект memcached в состояние closed. Любые последующие операции, кроме connect(), на текущем объекте будут возвращать ошибку closed.
get_reused_times
syntax: times, err = memc:get_reused_times()
Этот метод возвращает количество (успешно) повторно использованных раз для текущего соединения. В случае ошибки возвращает nil и строку, описывающую ошибку.
Если текущее соединение не поступает из встроенного пула соединений, то этот метод всегда возвращает 0, то есть соединение никогда не использовалось повторно (пока). Если соединение поступает из пула соединений, то возвращаемое значение всегда ненулевое. Таким образом, этот метод также можно использовать для определения, поступает ли текущее соединение из пула.
close
syntax: ok, err = memc:close()
Закрывает текущее соединение memcached и возвращает статус.
В случае успеха возвращает 1. В случае ошибок возвращает nil с строкой, описывающей ошибку.
add
syntax: 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
syntax: 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
syntax: 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
syntax: 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
syntax: value, flags, err = memc:get(key)
syntax: results, err = memc:get(keys)
Получает одну запись или несколько записей на сервере memcached через один ключ или таблицу ключей.
Сначала обсудим случай, когда ключ — это одна строка.
Значение ключа и связанное значение флагов будут возвращены, если запись найдена и не произошло ошибок.
В случае ошибок значения nil будут возвращены для value и flags, а также будет возвращено третье (строковое) значение для описания ошибки.
Если запись не найдена, то будут возвращены три значения nil.
Теперь обсудим случай, когда предоставляется таблица Lua с несколькими ключами.
В этом случае всегда будет возвращаться таблица Lua, содержащая пары ключ-результат в случае успеха. Каждое значение, соответствующее каждому ключу в таблице, также является таблицей, содержащей два значения: значение ключа и флаги ключа. Если ключ не существует, то в таблице results нет соответствующих записей.
В случае ошибок будет возвращено nil, а второе возвращаемое значение будет строкой, описывающей ошибку.
gets
syntax: value, flags, cas_unique, err = memc:gets(key)
syntax: results, err = memc:gets(keys)
Так же, как и метод get, но также будет возвращено уникальное значение CAS, связанное с записью, в дополнение к значению ключа и флагам.
Этот метод обычно используется вместе с методом cas.
cas
syntax: ok, err = memc:cas(key, value, cas_unique, exptime?, flags?)
Так же, как и метод set, но выполняет операцию проверки и установки, что означает "сохранить эти данные, но только если никто другой не обновил их с тех пор, как я их последний раз получал".
Аргумент cas_unique можно получить из метода gets.
touch
syntax: ok, err = memc:touch(key, exptime)
Обновляет время истечения существующего ключа.
Возвращает 1 при успехе или nil с строкой, описывающей ошибку в противном случае.
Этот метод был впервые представлен в релизе v0.11.
flush_all
syntax: ok, err = memc:flush_all(time?)
Немедленно очищает (или аннулирует) все существующие записи на сервере memcached (по умолчанию) или после истечения времени, указанного аргументом time (в секундах).
В случае успеха возвращает 1. В случае ошибок возвращает nil с строкой, описывающей ошибку.
delete
syntax: ok, err = memc:delete(key)
Немедленно удаляет ключ из memcached.
Ключ, который нужно удалить, должен уже существовать в memcached.
В случае успеха возвращает 1. В случае ошибок возвращает nil с строкой, описывающей ошибку.
incr
syntax: new_value, err = memc:incr(key, delta)
Увеличивает значение указанного ключа на целочисленное значение, указанное в аргументе delta.
Возвращает новое значение после увеличения в случае успеха и nil с строкой, описывающей ошибку в случае неудачи.
decr
syntax: new_value, err = memc:decr(key, value)
Уменьшает значение указанного ключа на целочисленное значение, указанное в аргументе delta.
Возвращает новое значение после уменьшения в случае успеха и nil с строкой, описывающей ошибку в случае неудачи.
stats
syntax: lines, err = memc:stats(args?)
Возвращает информацию о статистике сервера memcached с необязательным аргументом args.
В случае успеха этот метод возвращает таблицу lua, содержащую все строки вывода; в случае неудачи возвращает nil с строкой, описывающей ошибку.
Если аргумент args опущен, возвращается общая статистика сервера. Возможные значения аргумента args включают items, sizes, slabs и другие.
quit
syntax: ok, err = memc:quit()
Сообщает серверу закрыть текущее соединение memcached.
Возвращает 1 в случае успеха и nil в противном случае. В случае ошибок будет возвращено еще одно строковое значение для описания ошибки.
В общем, вы можете просто вызвать метод close, чтобы достичь того же эффекта.
verbosity
syntax: ok, err = memc:verbosity(level)
Устанавливает уровень подробности, используемый сервером memcached. Аргумент level должен быть указан только в целых числах.
Возвращает 1 в случае успеха и nil в противном случае. В случае ошибок будет возвращено еще одно строковое значение для описания ошибки.
init_pipeline
syntax: err = memc:init_pipeline(n?)
Включает режим конвейеризации Memcache. Все последующие вызовы методов команд Memcache будут автоматически буферизоваться и отправляться на сервер за один раз, когда будет вызван метод commit_pipeline, или отменяться при вызове метода cancel_pipeline.
Необязательный параметр n — это размер буферных таблиц. Значение по умолчанию — 4.
commit_pipeline
syntax: results, err = memc:commit_pipeline()
Выходит из режима конвейеризации, подтверждая все кэшированные запросы Memcache на удаленный сервер за один раз. Все ответы на эти запросы будут автоматически собраны и возвращены как если бы это был большой многообъемный ответ на высшем уровне.
Этот метод успешно возвращает таблицу lua. В случае неудачи возвращает строку lua, описывающую ошибку.
cancel_pipeline
syntax: 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.