evalsha / script load, in a Redis Cluster

1,286 views
Skip to first unread message

Dorian B.

unread,
Dec 4, 2015, 8:01:08 AM12/4/15
to Redis DB
Hi everyone,

I'm running a simple cluster with 3 masters and 3 slaves, and I've noticed that there is no way to simply load a script to all instances.

Let say I load a basic script using the following command on master1:

In > script load "return redis.call('get', \"foo\")"
Out> 7cd7b04f27d1e9d443c7fa66ae1a09124f741a8c

I cannot execute the following command on master2:

In > evalsha 7cd7b04f27d1e9d443c7fa66ae1a09124f741a8c 1 foo 0
Out> NOSCRIPT No matching script. Please use EVAL.

How the client is supposed to handle evalsha and script load in the context of a cluster? Let's say I initialize manually the known starting nodes (masters 1 to 3), what will happen when I later increase my cluster with a master 4 or if master 2 crashes and get restarted.
I can't see any solution but to use script exists command, and eventually loading the script if missing. But that's a call for something that is unlikely to happen. Also note that I cannot follow do: try evalsha, get an error, load the script and try again, because I'm sometimes calling script within a transaction.

In case it can help I'm working on a java project so I'm using Jedis 2.8.0.

Thanks,
Dorian.

Marc Gravell

unread,
Dec 4, 2015, 9:50:22 AM12/4/15
to redi...@googlegroups.com
Indeed, this is tricky. Some of this can be masked by the client  - for example, one option is for the the client library to deal  with the "SCRIPT LOAD" / "EVALSHA" (with the caller just specifying raw string-based scripts), and have the library track where it knows the "SCRIPT LOAD" has been executed in this run, but that still gets awkward with restarts (could track run-id, etc) and with "SCRIPT FLUSH" (gah). None of that is really a "solution" as such, and it is hugely client-library dependent...

--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
To post to this group, send email to redi...@googlegroups.com.
Visit this group at http://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/d/optout.



--
Regards,

Marc

Alexey Shuksto

unread,
Dec 5, 2015, 2:54:41 AM12/5/15
to Redis DB
I think that `evalsha -> error -> eval` is the most "universal" solution of them all. Mostly because it enables client NOT to remember "did we load script into Redis?" On a side note -- you are not required to call `script load` after `evalsha` error -- Redis will "load" script after first `eval` invocation, all you need to do is calculate SHA1 of your script yourself.

`evalsha` in a `multi/exec` is a problem though, but there are couple of possible solutions:

1. all keys of `multi/exec` should belong to one master, so you could determine that master and check `script exists` specifically for that and only that node right before start of `multi`;

2. incorporate all your `multi/exec` commands into script;

3. check if script really needs to be run in `multi/exec`. :)


пятница, 4 декабря 2015 г., 16:01:08 UTC+3 пользователь Dorian B. написал:
Reply all
Reply to author
Forward
0 new messages