首页 > 其他 > 详细

Redis中的Scan命令踩坑记

时间:2021-01-29 17:37:09      阅读:37      评论:0      收藏:0      [点我收藏+]
local c = 0
local resp = redis.call(SCAN,c,MATCH,authToken*,COUNT,10000)
c = tonumber(resp[1])
local dataList = resp[2]

for i=1,#dataList do
    local d = dataList[i]
    local ttl = redis.call(TTL,d)
    if ttl == -1 then
        redis.call(DEL,d)
    end
end

if c==0 then
  return all finished
else
  return end
end

技术分享图片

 

 看完之后恍然大悟。原来count选项后面跟的数字并不是意味着每次返回的元素数量,而是scan命令每次遍历字典槽的数量

我scan执行的时候每一次都是从游标0的位置开始遍历,而并不是每一个字典槽里都存放着我所需要筛选的数据,这就造成了我最后的一个现象:虽然我count后面跟的是10000,但是实际redis从开头往下遍历了10000个字典槽后,发现没有数据槽存放着我所需要的数据。所以我最后的dbsize数量永远停留在了124204个。

所以在使用scan命令的时候,如果需要迭代的遍历,需要每次调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程。

local c = tonumber(ARGV[1])
local resp = redis.call(SCAN,c,MATCH,authToken*,COUNT,10000)
c = tonumber(resp[1])
local dataList = resp[2]

for i=1,#dataList do
    local d = dataList[i]
    local ttl = redis.call(TTL,d)
    if ttl == -1 then
        redis.call(DEL,d)
    end
end

return c

 

Redis中的Scan命令踩坑记

原文:https://www.cnblogs.com/tracydzf/p/14345652.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!