Hi, doujiang
我做了个测试add,flush_all 1000000的性能
ffi = require("ffi")
ffi.cdef[[
typedef long time_t;
typedef struct timeval {
time_t tv_sec;
time_t tv_usec;
} timeval;
int gettimeofday(struct timeval* t, void* tzp);
]]
gettimeofday_struct = ffi.new("timeval")
local function gettimeofday()
ffi.C.gettimeofday(gettimeofday_struct, nil)
return tonumber(gettimeofday_struct.tv_sec) * 1000000 + tonumber(gettimeofday_struct.tv_usec)
end
local t0 = gettimeofday()
local stats = ngx.shared.stats
local i
for i = 1,1000000 do
stats:add("stats"..i, true)
end
local t1 = gettimeofday()
ngx.say("shm add runtime: " .. (t1 - t0) / 1000 .. "ms")
stats:flush_all()
local t2 = gettimeofday()
ngx.say("shm flush_all runtime: " .. (t2 - t1) / 1000 .. "ms")
shm add runtime: 1937.472ms
shm flush_all runtime: 2.462ms
貌似还行,基本不会影响到这个访问。
在 2016年1月28日星期四 UTC+8上午10:17:20,doujiang写道:
Hello,
在 2016年1月27日 下午4:18,Millken Chen
<mil...@gmail.com>写道:
我能想到的是
local ip_list_dict = ngx.shared.ip_list
local client_ip = ngx.var.remote_addr
local ok, err = ip_list_dict:incr("total", 0)
if not ok then
ip_list_dict:flush_all()
ip_list_dict:add("total", 0, 60)
end
local ok, err = ip_list_dict:safe_add(client_ip, 1)
if not ok then
ip_list_dict:incr("total", 1)
end
你这个实现里,有一个比较危险的:flush_all 是 O(n) 的操作,应该尽量避免的
有一个思路:
dict:add(client_ip, true, ttl)
-- 没错,布尔值比双精度短一些
-- ttl 可以动态计算出来,在你的计算区间内有效即可
-- dict 容量足够大的话,不需要担心 add 会 force remove
在 2016年1月27日星期三 UTC+8下午3:55:00,Millken Chen写道:
访问量的统计好做,直接用dict:incr("req", 1)。如果是统计唯一ip数,大家有什么好的方法?