Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
redis slave上info命令列出的过期密钥数与我看到的不一致_Redis - Fatal编程技术网

redis slave上info命令列出的过期密钥数与我看到的不一致

redis slave上info命令列出的过期密钥数与我看到的不一致,redis,Redis,当我对redis 3.2.4服务器运行redis cli中的info命令时,它会显示以下内容: expires=223518 但是,当我运行keys*命令并为每个键请求ttl,并且只打印出ttl>0的键时,我只看到几百个 我以为expires是过期键数的计数,但我甚至不在这个数的数量级之内 有人能确切地说明expires的含义吗?这是否包括要过期和以前过期但尚未收回的密钥 更新: 下面是我如何计算过期密钥的数量: task count_tmp_keys: :environment do

当我对redis 3.2.4服务器运行
redis cli
中的
info
命令时,它会显示以下内容:

expires=223518

但是,当我运行
keys*
命令并为每个键请求
ttl
,并且只打印出ttl>0的键时,我只看到几百个

我以为
expires
是过期键数的计数,但我甚至不在这个数的数量级之内

有人能确切地说明
expires
的含义吗?这是否包括要过期和以前过期但尚未收回的密钥


更新:

下面是我如何计算过期密钥的数量:

  task count_tmp_keys: :environment do
    redis = Redis.new(timeout: 100)
    keys = redis.keys '*'
    ct_expiring = 0

    keys.each do |k|
      ttl = redis.ttl(k)
      if ttl > 0
        ct_expiring += 1
        puts "Expiring: #{k}; ttl is #{ttl}; total: #{ct_expiring}"
        STDOUT.flush
      end
    end

    puts "Total expiring: #{ct_expiring}"
    puts "Done at #{Time.now}"
  end
当我运行这个脚本时,它显示我的总过期时间为78天

当我运行info时,它会显示
db0:keys=10237963,expires=224098,avg_ttl=0

因为224098比78大很多,我很困惑。是否有更好的方法让我获得所有225k过期密钥的列表

还有,我的平均ttl是多少?你不认为它是非零的吗


更新

我有新的信息和一个简单的,100%的本地这种情况的报告

复制:在笔记本电脑上本地设置两个redis进程。让一个成为另一个的奴隶。在从属进程上,设置以下各项:

config set slave-serve-stale-data yes
config set slave-read-only no
现在,连接到从属设备(而不是主设备)并运行:

10秒后,您将无法再访问foo,但
info
命令仍将显示您有一个密钥到期,平均ttl为0


有人能解释一下这种行为吗?

expires只返回将过期的密钥的大小,而不是时间

第3.2.4条的规定


它只计算
server.db[j].expires的大小。(注意j是数据库索引)。

expires
包含TTL将过期的现有密钥,不包括已过期的密钥。 示例(为了简洁起见,省略了
info
命令中的额外信息):

鉴于在您的情况下,您正在询问有关从机密钥过期的问题,请参见:

从机上的钥匙未有效过期,因此平均ttl为 从未计算过

avg_ttl从未在从机上初始化,因此它可以是任何情况 任意值驻留在该位置的内存中


因此,可以预期,
info
命令在从机上的行为不同。

Hi@DruvPathak——我刚刚分享了我的脚本。谢谢@esilver您能确认您正在连接shell中的同一个db以及脚本吗?@DruvPathak是的,我正在连接同一个db。另外-您从上面的代码片段中可以看到,这么多键的平均ttl怎么可能为零?这不是很可疑吗?谢谢你帮我解开这个谜!我已经接受了你的答案,并为清楚起见对其进行了更新。
set foo 1
expire foo 10
long long keys, vkeys;

keys = dictSize(server.db[j].dict);
vkeys = dictSize(server.db[j].expires);
if (keys || vkeys) {
    info = sdscatprintf(info,
        "db%d:keys=%lld,expires=%lld,avg_ttl=%lld\r\n",
        j, keys, vkeys, server.db[j].avg_ttl);
}
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> SETEX mykey1 1000 "1"
OK
127.0.0.1:6379> SETEX mykey2 1000 "2"
OK
127.0.0.1:6379> SETEX mykey3 1000 "3"
OK
127.0.0.1:6379> info
# Keyspace
db0:keys=3,expires=3,avg_ttl=992766
127.0.0.1:6379> SETEX mykey4 1 "4"
OK
127.0.0.1:6379> SETEX mykey5 1 "5"
OK
127.0.0.1:6379> info
# Keyspace
db0:keys=3,expires=3,avg_ttl=969898
127.0.0.1:6379> keys *
1) "mykey2"
2) "mykey3"
3) "mykey1"
127.0.0.1:6379>