有志者,事竟成... :)
首先将登录信息存储在排序集中。假设用户 id 123 在时间 456 使用用户名“foo”登录,您可以将其表示为:
ZADD logins 456 123:foo
注意:您还必须从该 Sorted Set 中删除旧元素,以免它失去控制。
接下来,您要搜索过去 10 分钟内的用户,因此您将使用ZRANGEBYSCORE
它。与其将整个东西运回您的客户,不如使用 Lua 来处理它并检查冲突。
以下脚本示例将上述所有内容包装在一起:
-- Keys: 1) The logins Sorted Set
-- Args: 1) The epoch value of 'now'
-- 2) The logged in user id
-- 3) The logged in user name
-- Get logins from the last 10 minutes
local l = redis.call('ZRANGEBYSCORE', KEYS[1], ARGV[1]-600, '+inf')
-- "Evict" old logins
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', '(' .. ARGV[1]-600)
-- Store the new login
redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2] .. ':' .. ARGV[3])
local c = {} -- detected name collision
for _, v in pairs(l) do
local p = v:find(':') -- no string.split in Lua
local i = v:sub(1,p-1) -- id
local n = v:sub(p+1) -- name
if n == ARGV[3] then
c[#c+1] = i
end
end
return c