lua-resty-memcached
基于 cosocket API 的 ngx_lua Lua memcached 客户端驱动
$ opm get openresty/lua-resty-memcached
名称
lua-resty-memcached - 基于 cosocket API 的 ngx_lua Lua memcached 客户端驱动
此库被认为是生产就绪的。
描述
此 Lua 库是 ngx_lua nginx 模块的 memcached 客户端驱动
http://wiki.nginx.org/HttpLuaModule
此 Lua 库利用了 ngx_lua 的 cosocket API,确保了 100% 的非阻塞行为。
请注意,至少需要 ngx_lua 0.5.0rc29 或 OpenResty 1.0.15.7。
概要
lua_package_path "/path/to/lua-resty-memcached/lib/?.lua;;";
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
-- or connect to a unix domain socket file listened
-- by a memcached server:
-- 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)
-- put it into the connection pool of size 100,
-- with 10 seconds max idle timeout
local ok, err = memc:set_keepalive(10000, 100)
if not ok then
ngx.say("cannot set keepalive: ", err)
return
end
-- or just close the connection right away:
-- local ok, err = memc:close()
-- if not ok then
-- ngx.say("failed to close: ", err)
-- return
-- end
';
}
}
方法
以下方法中提供的 key
参数将在发送到 memcached 服务器之前根据 URI 转义规则自动转义。
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 服务器正在监听的远程主机和端口或 memcached 服务器监听的本地 unix 域套接字文件。
在实际解析主机名并连接到远程后端之前,此方法将始终查找连接池以匹配此方法先前调用创建的空闲连接。
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(time)
为后续操作(包括 connect
方法)设置超时(以毫秒为单位)保护。
成功时返回 1,否则返回 nil 和描述错误的字符串。
set_keepalive
语法:
ok, err = memc:set_keepalive(max_idle_timeout, pool_size)
将当前 memcached 连接立即放入 ngx_lua cosocket 连接池中。
您可以指定连接在池中的最大空闲超时时间(以毫秒为单位)以及每个 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 服务器中的单个条目或多个条目。
让我们首先讨论当键是单个字符串的情况。
如果找到条目并且没有发生错误,则将返回键的值和关联的标志值。
如果发生错误,则 value
和 flags
将被转换为 nil
值,并且还将返回第三个(字符串)值来描述错误。
如果未找到条目,则将返回三个 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?)
立即(默认)或在 time
参数(以秒为单位)指定的到期时间后,刷新(或使无效)memcached 服务器中的所有现有条目。
成功时返回 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
等。
version
语法:
version, err = memc:version(args?)
返回服务器版本号,例如 1.2.8
。
如果发生错误,它将返回 nil
和描述错误的字符串。
quit
语法:
ok, err = memc:quit()
告诉服务器关闭当前 memcached 连接。
成功时返回 1
,否则返回 nil
。如果发生错误,还将返回另一个字符串值来描述错误。
通常,您可以直接调用 close
方法来达到相同的效果。
verbosity
语法:
ok, err = memc:verbosity(level)
设置 memcached 服务器使用的详细程度级别。level
参数应仅给出整数。
成功时返回 1
,否则返回 nil
。如果发生错误,还将返回另一个字符串值来描述错误。
自动错误日志记录
默认情况下,底层的 ngx_lua 模块会在发生套接字错误时进行错误日志记录。如果您已经在自己的 Lua 代码中进行了适当的错误处理,那么建议您通过关闭 ngx_lua 的 lua_socket_log_errors 指令来禁用此自动错误日志记录,即
lua_socket_log_errors off;
限制
此库不能在类似 set_by_lua、log_by_lua 和 header_filter_by_lua* 的代码上下文中使用,因为在这些上下文中 ngx_lua cosocket API 不可用。
resty.memcached
对象实例不能存储在 Lua 模块级别的 Lua 变量中,因为这样会导致同一个 nginx 工作进程处理的所有并发请求共享它(参见 http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker),并在并发请求尝试使用同一个resty.memcached
实例时导致严重的竞争条件。您应该始终在函数局部变量或ngx.ctx
表格中初始化resty.memcached
对象。这些地方对每个请求都有自己的数据副本。
待办事项
实现 memcached 管道 API。
实现 memcached ascii 协议的 UDP 部分。
作者
Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, CloudFlare Inc.
版权和许可
此模块根据 BSD 许可证授权。
版权所有 (C) 2012-2016,作者 Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, CloudFlare Inc.
保留所有权利。
在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用此软件,无论是否修改:
源代码的重新分发必须保留上述版权声明、此条件列表和以下免责声明。
二进制形式的重新分发必须在随发行版提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
此软件由版权所有者和贡献者“按原样”提供,任何明示或暗示的保证,包括但不限于对适销性和特定用途适用性的暗示保证均予以否认。在任何情况下,版权所有者或贡献者均不对任何直接的、间接的、偶然的、特殊的、惩罚性的或后果性的损害负责(包括但不限于替代商品或服务的采购;使用、数据或利润损失;或业务中断),无论其原因如何以及在任何责任理论下,无论是合同、严格责任或侵权行为(包括疏忽或其他原因),均与本软件的使用有关,即使已告知可能会发生此类损害。
另请参见
ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule
memcached 有线协议规范:http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt
该文档介绍了 lua-resty-mysql 库。
作者
张逸淳 "agentzh" (agentzh)
许可证
2bsd
版本
-
基于 cosocket API 的 ngx_lua Lua memcached 客户端驱动程序 2016-09-29 03:20:26