lua-resty-bloomd
基于 ngx_lua 的一个客户端库,用于与 bloomd 服务器交互 (https://github.com/armon/bloomd)
$ opm get jie123108/lua-resty-bloomd
名称
lua-resty-bloomd - 基于 ngx_lua 的一个客户端库,用于与 bloomd 服务器交互 (https://github.com/armon/bloomd)
Bloomd 是一个高性能的 C 服务器,用于向网络客户端公开布隆过滤器及其操作。
此库已准备好用于生产环境。
摘要
lua_package_path "/path/to/lua-resty-bloomd/lib/?.lua;;";
server {
location /test {
content_by_lua '
local bloomd = require("resty.bloomd")
local function debug(name, ok, err)
if type(err) == 'table' then
local t = {}
for k, v in pairs(err) do
table.insert(t, k .. ":" .. tostring(v))
end
err = table.concat(t, ",")
end
ngx.say(string.format("%15s -- ok: %5s, err: %s", name, tostring(ok), tostring(err)))
end
-- create a new instance and connect to the bloomd(127.0.0.1:8673)
local filter_obj = bloomd:new("127.0.0.1", 8673, 2000)
local function test_main()
local filter_name = "my_filter"
local capacity = 100001
local probability = 0.001
-- create a filter named filter_name
local ok, err = filter_obj:create(filter_name, capacity, probability)
debug("create-new", ok, err)
assert(ok == true)
-- assert(err == "Done", "err ~= 'Done'")
-- create a filter, the name is exist
local ok, err = filter_obj:create(filter_name, capacity, probability)
debug("create-exist", ok, err)
assert(ok == true)
assert(err == "Exists")
-- set a key, New
local ok, err = filter_obj:set(filter_name, 'my_key')
debug("set-new", ok, err)
assert(ok==true)
assert(err == "Yes")
-- set a key, Exist
local ok, err = filter_obj:set(filter_name, 'my_key')
debug("set-exist", ok, err)
assert(ok==true)
assert(err == "No")
-- check a key, Exist
local ok, err = filter_obj:check(filter_name, 'my_key')
debug("check-exist", ok, err)
assert(ok==true)
assert(err == "Yes")
-- check a key, Not Exist
local ok, err = filter_obj:check(filter_name, 'this_key_not_exist')
debug("check-not-exist", ok, err)
assert(ok==true)
assert(err == "No")
-- flush a filter
local ok, err = filter_obj:flush(filter_name)
debug("flush", ok, err)
assert(ok==true)
assert(err == "Done")
-- close a bloom filter
local ok, err = filter_obj:close(filter_name)
debug("close", ok, err)
assert(ok==true)
assert(err == "Done")
-- check a key, Exist
local ok, err = filter_obj:check(filter_name, 'my_key')
debug("check-exist", ok, err)
assert(ok==true)
assert(err == "Yes")
filter_obj:create("my_filter3", capacity, 0.001)
-- list all filter
local ok, filters = filter_obj:list(filter_name)
debug("list", ok, filters)
assert(ok==true)
assert(type(filters)=='table' and #filters==2)
for _,filter in ipairs(filters) do
if filter.name == filter_name then
assert(filter.size == 1)
end
end
filter_obj:drop('my_filter3')
-- Set many items in a filter at once(bulk command)
local ok, status = filter_obj:sets(filter_name, {"a", "b", "c"})
assert(ok)
assert(type(status)=='table')
err = table.concat(status, ' ')
debug("sets", ok, err)
assert(err == "Yes Yes Yes")
local ok, status = filter_obj:sets(filter_name, {"a", "b", "d"})
assert(ok)
assert(type(status)=='table')
err = table.concat(status, ' ')
debug("sets", ok, err)
assert(err == "No No Yes")
-- Checks if a list of keys are in a filter
local ok, status = filter_obj:checks(filter_name, {"a", "x", "c", "d", "e"})
assert(ok)
assert(type(status)=='table')
err = table.concat(status, ' ')
debug("checks", ok, err)
assert(err == "Yes No Yes Yes No")
-- Gets info about a filter
local ok, info = filter_obj:info(filter_name)
debug("info", ok, info)
assert(ok)
assert(type(info)=='table')
assert(info.capacity == capacity)
assert(info.probability == probability)
assert(info.size == 5)
-- drop a filter
local ok, err = filter_obj:drop(filter_name)
debug("drop", ok, err)
assert(ok==true)
assert(err == "Done")
-- Test filter not exist
local ok, err = filter_obj:drop(filter_name)
debug("drop-not-exist", ok, err)
assert(ok==false)
assert(err == "Filter does not exist")
-- create, close and clear a bloom filter, my_filter2 is still in disk.
local ok, err = filter_obj:create("my_filter2", 10000*20, 0.001)
debug("create-new", ok, err)
assert(ok == true)
assert(err == "Done", "err ~= 'Done'")
local ok, err = filter_obj:close("my_filter2")
debug("close", ok, err)
assert(ok==true)
assert(err == "Done")
local ok, err = filter_obj:clear("my_filter2")
debug("clear", ok, err)
assert(ok==true)
assert(err == "Done")
ngx.say("--------- all test ok --------------")
end
local ok, err = pcall(test_main)
if not ok then
filter_obj:close("my_filter")
filter_obj:close("my_filter2")
filter_obj:close("my_filter3")
assert(ok, err)
end
';
}
}
方法
new
语法: filter_obj = bloomd:new(host, port, timeout)
创建一个新的布隆过滤器对象。
输入:
host
是 bloomd 的主机,默认为 '127.0.0.1'。输入:
port
是 bloomd 的端口,默认为 8673。输入:
timeout
是超时时间(毫秒),默认为 5000 毫秒。
create
语法: ok, err = filter_obj:create(filter_name, capacity, prob, in_memory)
创建一个新的过滤器
输入:
filter_name
是过滤器的名称,可以包含字符 a-z、A-Z、0-9、. 和 _。输入:
capacity
指定过滤器将被创建以至少存储初始过滤器中的这么多项。默认为 0.001。输入:
prob
是提供的最大误报概率。输入:
in_memory
用于强制过滤器不持久化到磁盘。
list
语法: ok, filters = filter_obj:list(filter_prefix)
列出所有过滤器或与前缀匹配的过滤器。
输出:
ok
是列表状态。输出:
filters
是一个 Lua 表格,包含所有匹配的过滤器。
for _,filter in ipairs(filters) do
ngx.say(filter.name, ",", filter.probability, ",",
filter.storage, ",", filter.capacity, ",",filter.size)
end
drop
语法: ok, err = filter_obj:drop(filter_name)
删除一个过滤器(从磁盘删除)。成功返回 ok:true,err:'Done'
close
语法: ok, err = filter_obj:close(filter_name)
关闭一个过滤器(从内存中取消映射,但仍然可以访问)。成功返回 ok:true,err:'Done'
clear
语法: ok, err = filter_obj:clear(filter_name)
从列表中清除一个过滤器(删除内存,保留在磁盘上)
check
语法: ok, status = filter_obj:check(filter_name, key)
检查一个键是否在过滤器中。
输入:
status
为 'Yes'(key
存在于过滤器中)或 'No'(如果key
不存在于过滤器中)。
checks
语法: ok, status = filter_obj:checks(filter_name, keys)
检查键列表是否在过滤器中
输入:
keys
是一个包含一些键的表格。输出:
status
是一个包含每个键的状态('Yes' 或 'No')的表格。
set
语法: ok, status = filter_obj:set(filter_name, key)
在过滤器中设置一个项
输出:
status
为 'Yes'(key
已成功设置为过滤器)或 'No'(key
存在于过滤器中)。
sets
语法: ok, status = filter_obj:sets(filter_name, keys)
一次在过滤器中设置多个项
输入:
keys
是一个包含一些键的表格。输出:
status
是一个包含每个键的设置状态('Yes' 或 'No')的表格。
info
语法: ok, info = filter_obj:info(filter_name)
获取有关过滤器的信息
输出:
info
是一个类似于 `{in_memory:1,set_misses:3,checks:8,capacity:100001, probability:0.001,page_outs:1,size:5,check_hits:5, storage:240141,page_ins:1,set_hits:5,check_misses:3,sets:8}` 的表格。
flush
语法: ok, err = filter_obj:flush(filter_name)
刷新指定的过滤器。
安装
您需要使用您的 Nginx 编译 ngx_lua。
您需要配置 lua_package_path 指令,将您的 lua-resty-bloomd
源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径,例如
# nginx.conf
http {
lua_package_path "/path/to/lua-resty-bloomd/lib/?.lua;;";
...
}
然后在 Lua 中加载库
bloomd = require "resty.bloomd"
作者
刘晓杰 此模块根据 BSD 许可证授权。 版权所有 (C) 2015,由刘晓杰 保留所有权利。 在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用,无论是否修改。 源代码的重新分发必须保留上述版权声明、此条件列表和以下免责声明。 二进制形式的重新分发必须在随分发提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。 本软件由版权持有人和贡献者“按原样”提供,并且任何明示或暗示的保证,包括但不限于适销性和特定用途适用性的暗示保证,均被免除。在任何情况下,版权持有人或贡献者均不对任何直接、间接、偶然、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润损失;或业务中断),无论其原因如何以及在任何责任理论下,无论是合同、严格责任还是侵权行为(包括疏忽或其他)均不承担责任,即使已被告知此类损害的可能性。版权和许可
作者
jie123108@163.com
许可证
2bsd
依赖项
openresty >= 1.9.3.1
版本
-
基于 ngx_lua 的一个客户端库,用于与 bloomd 服务器交互 (https://github.com/armon/bloomd) 2016-11-11 15:40:35
-
基于 ngx_lua 的一个客户端库,用于与 bloomd 服务器交互 (https://github.com/armon/bloomd) 2016-11-11 15:30:41