2012-10-23 31 views
4

我目前正在开发需要增加几百个计数器这样每次调用缓存:redis可以禁用流水线命令的回复吗?

redis.pipelined do 
    keys.each{ |key| redis.incr key } 
end 

在我的分析,现在我看到了,我不需要的答复仍然由Redis的宝石收集并浪费一些有价值的时间。我能以某种方式告诉redis我对回复不感兴趣吗?有没有更好的方法来增加大量的值。

我事先没有找到MINCR命令,例如..

谢谢!

回答

5

是......至少在2.6。您可以在LUA脚本中执行此操作,并且只需使LUA脚本返回空结果即可。这是使用booksleeve客户端:

const int DB = 0; // any database number 
// prime some initial values 
conn.Keys.Remove(DB, new[] {"a", "b", "c"}); 
conn.Strings.Increment(DB, "b"); 
conn.Strings.Increment(DB, "c"); 
conn.Strings.Increment(DB, "c"); 

// run the script, passing "a", "b", "c", "c" to 
// increment a & b by 1, c twice 
var result = conn.Scripting.Eval(DB, 
    @"for i,key in ipairs(KEYS) do redis.call('incr', key) end", 
    new[] { "a", "b", "c", "c"}, // <== aka "KEYS" in the script 
    null); // <== aka "ARGV" in the script 

// check the incremented values 
var a = conn.Strings.GetInt64(DB, "a"); 
var b = conn.Strings.GetInt64(DB, "b"); 
var c = conn.Strings.GetInt64(DB, "c"); 

Assert.IsNull(conn.Wait(result), "result"); 
Assert.AreEqual(1, conn.Wait(a), "a"); 
Assert.AreEqual(2, conn.Wait(b), "b"); 
Assert.AreEqual(4, conn.Wait(c), "c"); 

或者做incrby同样的事情,经过“借”号作为参数,改变中间部分:

// run the script, passing "a", "b", "c" and 1, 1, 2 
// increment a & b by 1, c twice 
var result = conn.Scripting.Eval(DB, 
    @"for i,key in ipairs(KEYS) do redis.call('incrby', key, ARGV[i]) end", 
    new[] { "a", "b", "c" }, // <== aka "KEYS" in the script 
    new object[] { 1, 1, 2 }); // <== aka "ARGV" in the script 
+0

+1 2.6现在正在生产准备好,没有理由不升级。 – Mahn

+0

太棒了!完全忽略了脚本方法。非常感谢! –

2

不,这是不可能的。没有办法告诉Redis不回复。

避免在某些时候同步等待答复的唯一方法是运行一个完全异步的客户端(如异步模式下的node.js或hiredis)。

+0

非常有可能...在2.6 –

0

Redis的3.2版本支持这一明确:服务器

https://redis.io/commands/client-reply

客户REPLY命令控制是否将回复客户端的命令。以下模式可用: ON。这是服务器返回每个命令的默认模式。 OFF。在这种模式下,服务器不会回复客户端命令。 跳过。该模式在其之后立即跳过命令的回复。

返回值 使用OFF或SKIP子命令调用时,不进行回复。用ON调用时: 简单字符串回复:确定。