当前位置: 首页 > 面试题库 >

Redis从站上info命令列出的到期密钥数与我看到的不一致

牟黎昕
2023-03-14
问题内容

当我inforedis-cliredis 3.2.4服务器上运行命令时,它显示了过期时间:

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。

有人可以解释这种行为吗?


问题答案:

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命令在从站上的行为会有所不同。



 类似资料:
  • 问题内容: 当生存时间达到0时,我的Redis服务器不会删除密钥。 这是一个示例代码: 如果我通过redis检查信息返回,它说0个密钥已过期。 任何想法? 谢谢。 问题答案: 由于您正在执行“ …”,因此很难确定,但是我要说的是您在该部分设置了mykey,这将有效地消除过期。 从EXPIRE手册 仅当使用DEL命令删除密钥或使用SET或GETSET命令覆盖密钥时,才清除超时 另外,关于TTL的-1

  • 问题内容: 尝试使用键前缀存储过期时间x的值 我正在使用Redis。我目前正在使用hset存储值 我希望每个密钥都有不同的到期时间,因为我将分别存储每个密钥。 我该怎么做呢? 问题答案: 这不能直接完成。您可以在整个hset上添加有效期,但不能在单个字段上添加。如果要执行此操作,可以调用,其中是到期之前的秒数。 或者,您可以使用代替: 这将带走某些功能,因为(例如)您将没有一种好的方法来列出所有以

  • 我们如何在docker history命令输出的第三列(由创建)中看到完整命令? 第三列(CREATED BY)是命令的缩写,这使得重建原始Dockerfile变得困难。是否可以在第三列中获得完整的命令? 感谢阅读。

  • 问题内容: 我正在按照此示例在Dotnet Core上实现Redis缓存。 不幸的是,似乎Get(key)和GetString(key)都只返回值,而不是诸如过期之类的元数据。 当我使用redis-cli时,我可以使用来检索数据和元数据 有什么办法可以从我的代码访问此元数据? 当然,可能存在一些变通办法,例如在数据对象本身中添加有效期限或添加包含元数据的第二个键,但是这两种解决方案都不是很优雅。

  • 问题内容: 目前,我们在Windows上拥有Jenkins主服务器,Ubuntu从属服务器和Windows从属服务器。我正在尝试在Windows从站上设置git。安装了msysgit,并将目录包括在系统路径变量中,以便可以在任何地方调用“ git.exe”或“ git.cmd”。 在我的Jenkins配置中,我有一个带有私有SSH密钥的凭证。该凭据供詹金斯与Git一起使用。这适用于主节点和linu

  • 问题内容: 我们有以下用例:每当某个密钥过期时,我们都需要根据其值来得到通知并执行某些操作。但是,当redis触发该事件时,当我们稍后尝试访问它时,该密钥已经从数据库中删除了,这当然是可以预期的。 现在,有一种方法可以在过期后再次访问该条目?我猜不会。 第二种选择:有没有一种方法可以让redis在发送这些事件时发布整个值对象而不是仅仅发布键?我想可以通过Lua添加它,但是如果可能的话,我希望有一个