I'm currently developing a cache that needs increase a few hundred counters for every call like this:
redis.pipelined do
keys.each{ |key| redis.incr key }
end
In my profiling now I saw that the replies I don't need are still collected by the redis gem and waste some valueable time. Can I tell redis in some way that I'm not interested in the replies? Is there a better way to increment lots of values.
I didn't find a MINCR
command, for example..
Thanks in advance!
Redis pipelining is a technique for improving performance by issuing multiple commands at once without waiting for the response to each individual command. Pipelining is supported by most Redis clients. This document describes the problem that pipelining is designed to solve and how pipelining works in Redis.
Transactions vs Pipeline in Redis. The difference is pipelines are not atomic whereas transactions are atomic, meaning 2 transactions do not run at the same time, whereas multiple pipelines can be executed by Redis-server at the same time in an interleaved fashion.
It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands. This time due to the syntax error the bad INCR command is not queued at all.
Redis features two main mechanisms for executing multiple operations atomically: MULTI / EXEC transactions and Lua scripts.
Yes... in 2.6, at least. You could do this in a LUA script, and simply have the LUA script return an empty result. Here it is using the booksleeve client:
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");
Or to do the same thing with incrby
, passing the "by" numbers as arguments, change the middle portion to:
// 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With