在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 inredis-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 thettl
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
最满意答案
您可以平均使用
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, asCOALESCE
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.
相关问答
更多-
如何在SQL查询返回的结果下面选择10行?(How to select 10 rows below the result returned by the SQL query?)[2022-02-19]
您需要为结果定义一个订单来执行此操作。 否则,数据无法保证订单。 如果“接下来的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 ...