lua-resty-lrucache
基于 LuaJIT FFI 的 Lua 端 LRU 缓存
$ opm get openresty/lua-resty-lrucache
名称
lua-resty-lrucache - 基于 LuaJIT FFI 的 Lua 端 LRU 缓存
状态
此库被认为是生产就绪的。
概要
-- file myapp.lua: example "myapp" module
local _M = {}
-- alternatively: local lrucache = require "resty.lrucache.pureffi"
local lrucache = require "resty.lrucache"
-- we need to initialize the cache on the lua module level so that
-- it can be shared by all the requests served by each nginx worker process:
local c, err = lrucache.new(200) -- allow up to 200 items in the cache
if not c then
return error("failed to create the cache: " .. (err or "unknown"))
end
function _M.go()
c:set("dog", 32)
c:set("cat", 56)
ngx.say("dog: ", c:get("dog"))
ngx.say("cat: ", c:get("cat"))
c:set("dog", { age = 10 }, 0.1) -- expire in 0.1 sec
c:delete("dog")
c:flush_all() -- flush all the cached data
end
return _M
# nginx.conf
http {
lua_package_path "/path/to/lua-resty-lrucache/lib/?.lua;;";
server {
listen 8080;
location = /t {
content_by_lua '
require("myapp").go()
';
}
}
}
描述
此库为 OpenResty 和 ngx_lua 模块实现了一个简单的 LRU 缓存。
此缓存还支持过期时间。
LRU 缓存完全驻留在 Lua VM 中,并且受 Lua GC 的影响。因此,不要期望它跨操作系统进程边界共享。好处是可以缓存任意复杂的 Lua 值(如深度嵌套的 Lua 表),而无需序列化开销(如使用 ngx_lua
的 共享字典 API)。缺点是您的缓存始终局限于当前操作系统进程(如当前 nginx 工作进程)。在 init_by_lua 上下文中使用此库实际上没有意义,因为缓存不会被任何工作进程共享(除非您只想使用预定义的项“预热”缓存,这些项将通过 fork
被工作进程继承)。
此库包含两种不同的实现,以两种类的形式:resty.lrucache
和 resty.lrucache.pureffi
。它们共享完全相同的 API。唯一的区别是后者是纯 FFI 实现,它还为缓存查找实现了基于 FFI 的哈希表,而前者则使用本机 Lua 表。
如果缓存命中率相对较高,则应使用 resty.lrucache
类,它比 resty.lrucache.pureffi
更快。
但是,如果缓存命中率相对较低,并且插入到缓存中和从缓存中删除的键可能存在大量的变化,那么您应该使用 resty.lrucache.pureffi
,因为 Lua 表在设计上不擅长频繁删除键,并且您会看到 LuaJIT 运行时中的 resizetab
函数调用在 CPU 上的火焰图 中非常热,如果您在这种情况下使用 resty.lrucache
类而不是 resty.lrucache.pureffi
。
方法
要加载此库,
您需要在 ngx_lua 的 lua_package_path 指令中指定此库的路径。例如,
lua_package_path "/path/to/lua-resty-lrucache/lib/?.lua;;";
。您使用
require
将库加载到本地 Lua 变量中
local lrucache = require "resty.lrucache"
或
local lrucache = require "resty.lrucache.pureffi"
new
语法:cache, err = lrucache.new(max_items [, load_factor])
创建一个新的缓存实例。如果失败,则返回 nil
和描述错误的字符串。
max_items
参数指定缓存中保存的最大项目数。
load-factor
参数指定 resty.lrucache.pureffi
内部使用的基于 FFI 的哈希表的“负载因子”;默认值为 0.5(即 50%);如果指定负载因子,它将被限制在 [0.1, 1]
范围内(即如果负载因子大于 1,它将饱和到 1;同样,如果负载因子小于 0.1
,它将被限制到 0.1
)。此参数仅对 resty.lrucache.pureffi
有意义。
set
语法:cache:set(key, value, ttl)
设置一个带有值和过期时间的键。
ttl
参数指定过期时间段。时间值以秒为单位,但您也可以指定小数部分,如 0.25
。ttl
参数值为 nil 表示永远不会过期(这是默认值)。
当缓存已满时,缓存将自动驱逐最不常使用的项目。
get
语法:data, stale_data = cache:get(key)
使用键获取值。如果键在缓存中不存在或已过期,则将返回 nil
值。
从 v0.03
开始,如果可用,陈旧数据也将作为第二个返回值返回。
delete
语法:cache:delete(key)
从缓存中删除由键指定的项目。
flush_all
语法:cache:flush_all(key)
刷新当前缓存实例中所有现有数据(如果有)。这是一个 O(1)
操作,应该比创建全新的缓存实例快得多。
注意:resty.lrucache.pureffi
的 flush_all()
方法是一个 O(n)
操作。
先决条件
安装
建议直接使用最新的 OpenResty 包。至少需要 OpenResty 1.4.2.9。在构建 OpenResty 包时,您需要通过将 --with-luajit
选项传递给其 ./configure
脚本来启用 LuaJIT。不需要额外的 Nginx 配置。
如果您想将此库与您自己的 Nginx 构建(使用 ngx_lua)一起使用,那么您需要确保您至少使用的是 ngx_lua 0.8.10。
此外,您需要配置 lua_package_path 指令,将您的 lua-resty-lrucache 源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径中,如下所示
# nginx.conf
http {
lua_package_path "/path/to/lua-resty-lrucache/lib/?.lua;;";
...
}
然后在 Lua 中加载库
local lrucache = require "resty.lrucache"
待办事项
添加新的方法
get_stale
用于获取已过期的项目。
社区
英文邮件列表
The openresty-en 邮件列表适用于英语使用者。
中文邮件列表
The openresty 邮件列表适用于中文使用者。
错误和补丁
请通过以下方式报告错误或提交补丁
在 GitHub 问题跟踪器 上创建工单,
或发布到 "OpenResty 社区" 中。
作者
Yichun "agentzh" Zhang (章亦春) <[email protected]>,OpenResty Inc.
Shuxin Yang.
版权和许可
此模块在 BSD 许可下发布。
版权所有 (C) 2014-2018,由 Yichun "agentzh" Zhang,OpenResty Inc.
版权所有 (C) 2014-2017,由 Shuxin Yang。
保留所有权利。
只要满足以下条件,就可以在源代码和二进制形式中重新分发和使用此软件,无论是否修改。
源代码的重新分发必须保留上述版权声明、此条件列表和以下免责声明。
二进制形式的重新分发必须在随分发提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
本软件由版权所有者和贡献者“按现状”提供,任何明示或暗示的保证,包括但不限于适销性和特定用途适用性的暗示保证均被免除。在任何情况下,版权所有者或贡献者都不对因使用本软件而引起的任何直接、间接、偶然、特殊、示范性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润损失;或业务中断)负责,无论任何责任理论,无论是基于合同、严格责任或侵权(包括疏忽或其他原因)而产生的,即使已告知存在此类损害的可能性。
另请参阅
ngx_lua 模块:https://github.com/chaoslawful/lua-nginx-module
OpenResty:https://openresty.org.cn
作者
Yichun Zhang (agentzh)
许可证
2bsd
依赖关系
luajit
版本
-
基于 LuaJIT FFI 的 Lua 端 LRU 缓存 2018-04-19 20:12:47
-
基于 LuaJIT FFI 的 Lua 端 LRU 缓存 2017-08-08 22:47:34
-
基于 LuaJIT FFI 的 Lua 端 LRU 缓存 2017-04-08 22:37:41
-
基于 LuaJIT FFI 的 Lua 端 LRU 缓存 2016-09-29 01:29:29