首页 \ 问答 \ 在redis slave上由info命令列出的过期密钥数量与我看到的不一致(Number of expiring keys listed by info command on redis slave not consistent with what I see)

在redis slave上由info命令列出的过期密钥数量与我看到的不一致(Number of expiring keys listed by info command on redis slave not consistent with what I see)

当我在redis-cli对redis 3.2.4服务器运行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个到期

当我运行信息时,它说db0:keys=10237963,expires=224098,avg_ttl=0

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

另外,我的平均ttl是0怎么样? 你不期望它是非零的吗?


UPDATE

我有新的信息和本地这种情况的简单,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。

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


When I run the info command in redis-cli against a redis 3.2.4 server, it shows me this for expires:

expires=223518

However, when I then run a keys * command and ask for the ttl for each key, and only print out keys with a ttl > 0, I only see a couple hundred.

I thought that the expires is a count of the number of expiring keys but I am not even within an order of magnitude of this number.

Can someone clarify exactly what expires is meant to convey? Does this include both to-be-expired and previously expired but not yet evicted keys?


Update:

Here is how I counted the number of keys expiring:

  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

When I ran this script it shows I have a total expiring of 78

When I run info, it says db0:keys=10237963,expires=224098,avg_ttl=0

Because 224098 is so much larger than 78, I am very confused. Is there perhaps a better way for me to obtain a list of all 225k expiring keys?

Also, how is it that my average ttl is 0? Wouldn't you expect it to be nonzero?


UPDATE

I have new information and a simple, 100% repro of this situation locally!

To repro: setup two redis processes locally on your laptop. Make one a slave of the other. On the slave process, set the following:

config set slave-serve-stale-data yes
config set slave-read-only no

Now, connect to the slave (not the master) and run:

set foo 1
expire foo 10

After 10 seconds, you will no longer be able to access foo, but info command will still show that you have 1 key expiring with an average ttl of 0.

Can someone explain this behavior?


原文:https://stackoverflow.com/questions/45844944
更新时间:2023-06-13 21:06

最满意答案

您可以平均使用COALESCE - 换句话说,如果在您的平均查询中找不到结果,您将改为显示0.00而不是NULL,因为COALESCE将转换为第一个非null参数。

我在本地复制了您的数据库,并使用所有国家/地区字符串进行了测试,并使用以

SELECT c.carID, c.description, c.model, cy.name, ct.description,
           COALESCE(l.avgLikes,'0.00') AS 'avglikes'
    FROM Cars c 
    INNER JOIN Country cy ON c.countryID = cy.countryID  AND cy.name = "Germany" 
    INNER JOIN CarType ct ON c.carTypeID = ct.carTypeID 
    LEFT JOIN
         (SELECT l.carId, AVG(Likes) as avgLikes
          FROM Likes l
          GROUP BY l.CarId
         ) l
         ON c.carID = l.carID 

简单,但希望成功的解决方案。


You could use a COALESCE on average likes - in other words, if no results are found in your average query, you will instead show 0.00 instead of NULL, as COALESCE will translate to the first non-null parameter.

I copied your database locally and tested with all country strings and got the expected output using:

SELECT c.carID, c.description, c.model, cy.name, ct.description,
           COALESCE(l.avgLikes,'0.00') AS 'avglikes'
    FROM Cars c 
    INNER JOIN Country cy ON c.countryID = cy.countryID  AND cy.name = "Germany" 
    INNER JOIN CarType ct ON c.carTypeID = ct.carTypeID 
    LEFT JOIN
         (SELECT l.carId, AVG(Likes) as avgLikes
          FROM Likes l
          GROUP BY l.CarId
         ) l
         ON c.carID = l.carID 

Simple, but hopefully successful solution for you.

相关问答

更多
  • 您需要为结果定义一个订单来执行此操作。 否则,数据无法保证订单。 如果“接下来的2行”表示“在该特定行之后插入表中的下两条记录”,则需要使用自动递增字段或“日期创建”时间戳字段来执行此操作。 You need to define an order to the results to do this. There is no guaranteed order to the data otherwise. If by "the next 2 rows after" you mean "the next 2 re ...
  • 您可以平均使用COALESCE - 换句话说,如果在您的平均查询中找不到结果,您将改为显示0.00而不是NULL,因为COALESCE将转换为第一个非null参数。 我在本地复制了您的数据库,并使用所有国家/地区字符串进行了测试,并使用以 SELECT c.carID, c.description, c.model, cy.name, ct.description, COALESCE(l.avgLikes,'0.00') AS 'avglikes' FROM Cars c ...
  • 有几种方法可以获得返回的行数,最常见的是在MySQL中运行COUNT(*) ,但也有mysqli_num_rows($result) (不是你使用的num_rows() ,除非你自己创建了这个函数)。 mysqli_stmt_num_rows()仅在您使用prepare()而不是query()时才有效。 在ordre中使用COUNT(*)你必须首先运行并获取查询,而mysqli_num_rows()是MySQLiResult对象返回的常量,如果查询没有失败,你可以使用它。 我修改了你要检查查询是否实际成功的 ...
  • 这应该是你想要的。 完整列不应包含在GROUP BY中,并且应该相加。 SELECT DISTINCT wo.work_order_no, wos.status_description, wo.order_qty AS [ORDERQTY], SUM(p.good_tot_diff) AS [COMPLETE], (sum(p.good_tot_diff)/wo.order_qty) * 100 AS [PERCENTCOMPLETE] FROM wo_master AS wo, process ...
  • 可能没有什么理由: 表tblledger有20条匹配billid记录(所谓的重复记录来自tblbill中的相同4条记录,您应该计算不同的值以确定是否存在重复) 运行第一个查询后,该数据已更改。 任何方式都没有隐藏记录这样的东西 There could be few reasons: There are 20 records with matching billid in table tblledger (the so called duplicate records came from the same 4 ...
  • 我在想你的子查询返回多于一行,因此用“IN”替换你的“=”。 喜欢这个... SELECT * FROM commenttoarticle a WHERE a.idCommentToArticle IN (SELECT CommentToArticlePID FROM commenttoarticle b) ORDER BY a.idCommentToArticle DESC LIMIT 3 I am thinking that your subquery returns more than 1 r ...
  • SQL Server需要alias 。 将缺少的alias添加到子选择以修复错误。 SELECT Count(*) FROM (SELECT c1, Count(*) cnt FROM table GROUP BY c1 HAVING Count(*) > 1) a; --here 但是有一个更简单的版本 SELECT TOP 1 Count(*)OVER() -- Distinct Count(*)OVE ...
  • 这是因为NOT IN (NULL) 始终为false select t.name, t.company from company t inner join employee e on t.id = e.emp_id where t.name not in(select null from dual) 会是一样的。 使用NOT EXISTS代替: select t.name, t.company from company t join employee e on t.id = e.emp_id ...
  • 以下这一行只获取1行: $apps = $stmt->fetch(PDO::FETCH_ASSOC); 请改用fetchAll : $apps = $stmt->fetchAll(PDO::FETCH_ASSOC); This line below only fetches 1 row: $apps = $stmt->fetch(PDO::FETCH_ASSOC); Use fetchAll instead: $apps = $stmt->fetchAll(PDO::FETCH_ASSOC);
  • 检查SqlDataReader上的HasRows属性您可能需要首先执行检查,然后查看是否有返回的行,然后是否有,然后继续阅读。 If ($Reader.HasRows) { //read your rows. } else { no rows returned... } Check for the HasRows property on the SqlDataReader You might want to do the if check first and see whether ...

相关文章

更多

最新问答

更多
  • 如何检索Ember.js模型的所有属性(How to retrieve all properties of an Ember.js model)
  • maven中snapshot快照库和release发布库的区别和作用
  • arraylist中的搜索元素(Search element in arraylist)
  • 从mysli_fetch_array中获取选定的值并输出(Get selected value from mysli_fetch_array and output)
  • Windows Phone上的可用共享扩展(Available Share Extensions on Windows Phone)
  • 如何在命令提示符下将日期设置为文件名(How to set file name as date in command prompt)
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • 从iframe访问父页面的id元素(accessing id element of parent page from iframe)
  • linux的常用命令干什么用的
  • Feign Client + Eureka POST请求正文(Feign Client + Eureka POST request body)
  • 怎么删除禁用RHEL/CentOS 7上不需要的服务
  • 为什么Gradle运行测试两次?(Why does Gradle run tests twice?)
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在android中的活动之间切换?(Switching between activities in android?)
  • Perforce:如何从Depot到Workspace丢失文件?(Perforce: how to get missing file from Depot to Workspace?)
  • Webform页面避免运行服务器(Webform page avoiding runat server)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 内存布局破解(memory layout hack)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • 我们可以有一个调度程序,你可以异步添加东西,但会同步按顺序执行吗?(Can we have a dispatcher that you can add things todo asynchronously but will be executed in that order synchronously?)
  • “FROM a,b”和“FROM a FULL OUTER JOIN b”之间有什么区别?(What is the difference between “FROM a, b” and “FROM a FULL OUTER JOIN b”?)
  • Java中的不可变类(Immutable class in Java)
  • bat批处理文件结果导出到txt
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • 德州新起点计算机培训学校主要课程有什么?
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • “latin1_german1_ci”整理来自哪里?(Where is “latin1_german1_ci” collation coming from?)