Need atomic multi hincryby by lua scripts.

evalsha slower than eval:

EVAL: local j=1;local results={};for i=1,#ARGV,2 do local f=ARGV[i];local v=ARGV[i+1];results[j]=redis.call('hincrby','r3c_eval_0',f,v);j=j+1; end;return results;

EVALSHA: local j=1;local results={};for i=1,#ARGV,2 do local f=ARGV[i];local v=ARGV[i+1];results[j]=redis.call('hincrby','r3c_eval_0',f,v);j=j+1; end;return results;

Comment From: badboy

(D'oh! I managed to post & delete a comment, so here once again)

Can't reproduce that locally:

$ redis-cli -x script load < script1.lua
"b91594bd37521716af19905a9ae0d3fc9c62a037"
$ code/redis/src/redis-benchmark eval "$(<script1.lua)" 0 a 4 c 5 | tail -2 | head -1
114810.56 requests per second
$ redis-benchmark evalsha b91594bd37521716af19905a9ae0d3fc9c62a037 0 a 4 c 5 | tail -2 | head -1
125786.16 requests per second

EVALSHA is consistently faster than EVAL. (Run on an otherwise empty Redis instance on my laptop). The time difference is easily explained by the re-hashing of the script on each invocation of EVAL.

If you see different results you might want to post those and maybe look into other factors of your system as well. Keep in mind that this issue tracker should be used for bugs or improvements to the Redis server. For questions like yours please it might be better to ask on /r/redis, the mailing list or ask in the irc channel #redis on freenode.

Comment From: eyjian

$ cat s.lua local j=1;local results={};for i=1,#ARGV,2 do local f=ARGV[i];local v=ARGV[i+1];results[j]=redis.call('hincrby','r3c_eval_0',f,v);j=j+1; end;return results;

$ redis-cli -x script load < s.lua "b91594bd37521716af19905a9ae0d3fc9c62a037"

$ redis-benchmark eval "$(<s.lua)" 1 r3c_eval_0 f0 0 f1 1 f2 2 f3 3 f4 4 f5 5 f6 6 f7 7 f8 8 f9 9 |tail -2 |head -1 20032.05 requests per second

$ redis-benchmark evalsha "b91594bd37521716af19905a9ae0d3fc9c62a037" 1 r3c_eval_0 f0 0 f1 1 f2 2 f3 3 f4 4 f5 5 f6 6 f7 7 f8 8 f9 9 |tail -2 |head -1 17170.33 requests per second

Comment From: eyjian

EVALSHA slower than EXPIRE & SETNX

1) setnxex: EVAL (EVALSHA) redis->eval("local n;n=redis.call('setnx',KEYS[1],ARGV[1]);if (n>0) then redis.call('expire',KEYS[1],ARGV[2]) end;return n;", value, 3600); // eval will call EVALSHA except the first time.

2) EXPIRE & SETNX redis->expire(key, 3600); redis->setnx(key, value);

Comment From: yangzhongj

DO you have certain answer for this issue.

Comment From: filipecosta90

confirmed that EVALSHA is behaving as expected on a stable env with 2 VMs. - EVALSHA p50 latency including RTT is lower than EVAL even while doing higher ops/sec - EVALSHA throughput is higher by around 4% vs EVAL as expected

marking this issue to be closed.

taskset -c 0-3 memtier_benchmark -s 10.3.0.140 --command "EVAL \"$(<s.lua)\" 1 r3c_eval_0 f0 0 f1 1 f2 2 f3 3 f4 4 f5 5 f6 6 f7 7 f8 8 f9 9" --json-out-file eval.json --test-time 120 --hide-histogram
Json file eval.json created...
Writing results to stdout
[RUN #1] Preparing benchmark client...
[RUN #1] Launching threads now...
[RUN #1 100%, 120 secs]  0 threads:     6586219 ops,   54481 (avg:   54882) ops/sec, 23.90MB/sec (avg: 23.99MB/sec),  3.67 (avg:  3.64) msec latency

4         Threads
50        Connections per thread
120       Seconds


ALL STATS
==================================================================================================
Type         Ops/sec    Avg. Latency     p50 Latency     p99 Latency   p99.9 Latency       KB/sec 
--------------------------------------------------------------------------------------------------
Evals       54882.54         3.64298         3.32700         6.68700         7.77500     24568.08 
Totals      54882.54         3.64298         3.32700         6.68700         7.77500     24568.08 

EVALSHA

taskset -c 0-3 memtier_benchmark -s 10.3.0.140 --command "EVALSHA b91594bd37521716af19905a9ae0d3fc9c62a037 1 r3c_eval_0 f0 0 f1 1 f2 2 f3 3 f4 4 f5 5 f6 6 f7 7 f8 8 f9 9" --json-out-file evalsha.json --test-time 120  --hide-histogram
Json file evalsha.json created...
Writing results to stdout
[RUN #1] Preparing benchmark client...
[RUN #1] Launching threads now...
[RUN #1 100%, 120 secs]  0 threads:     6827748 ops,   56547 (avg:   56896) ops/sec, 18.86MB/sec (avg: 18.85MB/sec),  3.53 (avg:  3.51) msec latency

4         Threads
50        Connections per thread
120       Seconds


ALL STATS
===================================================================================================
Type          Ops/sec    Avg. Latency     p50 Latency     p99 Latency   p99.9 Latency       KB/sec 
---------------------------------------------------------------------------------------------------
Evalshas     56896.19         3.51401         3.21500         6.46300         7.61500     19303.02 
Totals       56896.19         3.51401         3.21500         6.46300         7.61500     19303.02