在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.

相关问答

更多

如何在SQL查询返回的结果下面选择10行?(How to select 10 rows below the result returned by the SQL query?)

您需要为结果定义一个订单来执行此操作。 否则,数据无法保证订单。 如果“接下来的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...

尽管SQL查询,仍返回零行(Zero rows being returned, despite SQL Query)

您可以平均使用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...

PHP - 获取sql select查询返回的行数(PHP - get number of rows returned by a sql select query)

有几种方法可以获得返回的行数,最常见的是在MySQL中运行COUNT(*) ,但也有mysqli_num_rows($result) (不是你使用的num_rows() ,除非你自己创建了这个函数)。 mysqli_stmt_num_rows()仅在您使用prepare()而不是query()时才有效。 在ordre中使用COUNT(*)你必须首先运行并获取查询,而mysqli_num_rows()是MySQLiResult对象返回的常量,如果查询没有失败,你可以使用它。 我修改了你要检查查询是否...

SQL返回4行时的2行总和(SQL Sum of 2 rows when 4 rows are returned)

这应该是你想要的。 完整列不应包含在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, pro...

SQL - 查询返回可能不存在的行(SQL - query returning rows that presumably do not exist)

可能没有什么理由: 表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 s...

从子查询SQL返回所有行?(Return all rows from sub-query SQL?)

我在想你的子查询返回多于一行,因此用“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 tha...

如何从子查询中获取返回的行(how to get returned rows from a sub query)

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(...

使用NOT IN的SQL查询不返回任何行(SQL query with NOT IN returning no rows)

这是因为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.em...

PHP SQL查询不返回与phpMyAdmin中相同的行(PHP SQL query not returning same rows as in phpMyAdmin)

以下这一行只获取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)...

PowerShell:如何确定SQL查询是否返回0行(PowerShell: How to determine if SQL query returns 0 rows)

检查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 wh...

相关文章

更多

redis 集群环境搭建-redis集群管理

集群架构 (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度 ...

Redis Cookbook

Two years since its initial release, Redis already ...

Redis概述

什么是Redis Redis是Remote Dictionary Server的缩写, Redis是一 ...

redis主从从架构搭建-redis集群管理

主从从架构 [root@master redis-master-slave]# vim 6382/re ...

redis 集群使用主从复制架构-redis集群管理

redis集群使用主从架构如下图,能有效解决集群中节点连接不上造成集群挂掉的情况 a) 在Redis ...

redis主从复制的原理-redis集群管理

复制的过程原理 1、 当从库和主库建立master-slave关系后,会向主数据库发送SYNC命令; ...

redis从库只读设置-redis集群管理

默认情况下redis数据库充当slave角色时是只读的不能进行写操作,如果写入,会提示以下错误:REA ...

redis sentinel(哨兵) 配置详解-redis集群管理

1. redis sentinel(哨兵) redis sentinel(哨兵)是对Redis系统的 ...

Redis配置文件详解

redis是一款开源的、高性能的键-值存储(key-value store),和memcached类似 ...

最新问答

更多

获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)

我用Google搜索了一个解决方案。 “EnumDisplayModeProvider”是我自己设置网站的各种模式的枚举。 public EnumDisplayModeProvider GetDisplayModeId() { foreach (var mode in DisplayModeProvider.Instance.Modes) if (mode.CanHandleContext(HttpContext)) {

如何通过引用返回对象?(How is returning an object by reference possible?)

这相对简单:在类的构造函数中,您可以分配内存,例如使用new 。 如果你制作一个对象的副本,你不是每次都分配新的内存,而是只复制指向原始内存块的指针,同时递增一个也存储在内存中的引用计数器,使得每个副本都是对象可以访问它。 如果引用计数降至零,则销毁对象将减少引用计数并仅释放分配的内存。 您只需要一个自定义复制构造函数和赋值运算符。 这基本上是共享指针的工作方式。 This is relatively easy: In the class' constructor, you allocate m

矩阵如何存储在内存中?(How are matrices stored in memory?)

正如它在“熵编码”中所说的那样,使用Z字形图案,与RLE一起使用,在许多情况下,RLE已经减小了尺寸。 但是,据我所知,DCT本身并没有给出稀疏矩阵。 但它通常会增强矩阵的熵。 这是compressen变得有损的点:输入矩阵用DCT传输,然后量化量化然后使用霍夫曼编码。 As it says in "Entropy coding" a zig-zag pattern is used, together with RLE which will already reduce size for man

每个请求的Java新会话?(Java New Session For Each Request?)

你是如何进行重定向的? 您是否事先调用了HttpServletResponse.encodeRedirectURL()? 在这里阅读javadoc 您可以使用它像response.sendRedirect(response.encodeRedirectURL(path)); The issue was with the path in the JSESSIONID cookie. I still can't figure out why it was being set to the tomca

css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)

我认为word-break ,如果你想在一个单词中打破行,你可以指定它,这样做可以解决问题: .column { word-break:break-all; } jsFiddle演示。 您可以在此处阅读有关word-break属性的更多信息。 I think word-break, with which you can specify if you want to break line within a word, will do the trick: .column { word-break

无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)

我认为您忘记在分类时间内缩放输入图像,如train_test.prototxt文件的第11行所示。 您可能应该在C ++代码中的某个位置乘以该因子,或者使用Caffe图层来缩放输入(请查看ELTWISE或POWER图层)。 编辑: 在评论中进行了一次对话之后,结果发现在classification.cpp文件中错误地删除了图像均值,而在原始训练/测试管道中没有减去图像均值。 I think you have forgotten to scale the input image during cl

xcode语法颜色编码解释?(xcode syntax color coding explained?)

转到: Xcode => Preferences => Fonts & Colors 您将看到每个语法高亮颜色旁边都有一个简短的解释。 Go to: Xcode => Preferences => Fonts & Colors You'll see that each syntax highlighting colour has a brief explanation next to it.

在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)

你考虑过第三方拼写检查吗? 您可以将在C#中开发的自定义WinForms控件插入访问数据库吗? VB6控件怎么样? 如果你能找到一个使用第三方库进行拼写检查的控件,那可能会有效。 Have you considered a third party spell checker? Can you insert a custom WinForms controls developed in C# into an access database? What about a VB6 control? If

从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)

我有同样的问题,因为我在远程服务器上有两个图像,我需要在每天的预定义时间复制到我的本地服务器,这是我能够提出的代码... try { if(@copy('url/to/source/image.ext', 'local/absolute/path/on/server/' . date("d-m-Y") . ".gif")) { } else { $errors = error_get_last(); throw new Exception($err

从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))

我不确定我完全明白你在说什么。 你能编辑你的帖子并包含你正在做的Subversion命令/操作的特定顺序吗? 最好使用命令行svn客户端,以便容易为其他人重现问题。 如果您只是想获取文件的旧副本(即使该文件不再存在),您可以使用如下命令: svn copy ${repo}/trunk/moduleA/file1@${rev} ${repo}/trunk/moduleB/file1 其中${repo}是您的存储库的URL, ${rev}是您想要的文件的版本。 这将恢复该文件的旧版本,包括最高版本