Question

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!

Was it helpful?

Solution

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

OTHER TIPS

No, this is not possible. There is no way to tell Redis to not reply.

The only way to avoid waiting synchronously for replies at some points is to run a fully asynchronous client (like node.js or hiredis in asynchronous mode).

Version 3.2 of Redis supports this explicitly:

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

The CLIENT REPLY command controls whether the server will reply the client's commands. The following modes are available: ON. This is the default mode in which the server returns a reply to every command. OFF. In this mode the server will not reply to client commands. SKIP. This mode skips the reply of command immediately after it.

Return value When called with either OFF or SKIP subcommands, no reply is made. When called with ON: Simple string reply: OK.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top