当我在info
中针对redis 3.2.4服务器运行redis-cli
命令时,它会显示此信息已过期:
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
当我运行信息时,它会显示db0:keys=10237963,expires=224098,avg_ttl=0
因为224098比78大得多,所以我很困惑。有没有更好的方法让我获得所有225k到期密钥的列表?
另外,我的平均ttl是0是多少?你不期望它是非零的吗?
更新
我在本地获得了新信息和简单的100%责备这种情况!
要复制:在笔记本电脑上本地设置两个redis进程。让一个成为另一个的奴隶。在从属进程中,设置以下内容:
config set slave-serve-stale-data yes
config set slave-read-only no
现在,连接到从站(不是主站)并运行:
set foo 1
expire foo 10
10秒后,您将无法再访问foo,但info
命令仍会显示您的1个密钥到期,平均ttl为0。
有人可以解释这种行为吗?
答案 0 :(得分:2)
expires只返回将过期的密钥大小。
3.2.4的source code
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);
}
它只计算server.db[j].expires
的大小。 (注意j是数据库索引)。
答案 1 :(得分:1)
expires
包含现有的TTL密钥,该密钥将过期,不包括已过期的密钥。
示例(为简洁起见,遗漏了info
命令中的额外信息):
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>
鉴于在您的情况下,您询问奴隶的密钥到期,按https://github.com/antirez/redis/issues/2861:
奴隶上的键没有主动过期,因此avg_ttl是 从未计算过
根据https://groups.google.com/forum/#!topic/redis-db/NFTpdmpOPnc:
avg_ttl永远不会在奴隶上初始化,因此它可以是永远的 任意值驻留在那个地方的内存中。
因此,可以预期info
命令在从属上的行为不同。