Redis load Lua script and cache it from file (instead of SCRIPT LOAD)
Asked Answered
B

3

12

I understand that the common way of running Lua scripts with EVALSHA is to is to load the script first by passing it with SCRIPT LOAD. However, from my understanding, if the Redis server unexpectedly reboots, for example, the cached script will no longer exist and will have to be reloaded with SCRIPT LOAD.

Is there some way to set the Redis server to automatically load some specified Lua scripts from a file into its cache upon startup so they can be reliably executed with EVALSHA without worrying about the script possibly being unloaded?

Behalf answered 30/7, 2017 at 23:28 Comment(5)
There's no built-in way to do that. You have to reload those script on the client side.Etheline
I second @for_stack's comment/answerSybarite
On second thoughts, might it work to call redis-cli SCRIPT LOAD "$(cat myscript.lua)" right after starting redis (can specify that in my docker-compose as I'm using docker)? To have the script loaded every time after startup? The problem is, even if this works, is this bad practice? I have to be 100% sure I'm not going to ever encounter the script being unloaded accidentally.Behalf
i found that the redis-cli script load $(cat myscript.lua) approach only keeps the most recently loaded script in cache -others are not available in cache when I call EVALSHA - has anyone else seen this behaviour?Rentfree
To load a multiline script from a file: redis-cli -x script load < myscript.lua. The $(cat myscript.lua) converts LFs to spaces unless you temporarily set IFS=" " in bash.Gary
E
9

Thank you for the comment done by Curtis Yallop I can finally load myscript.lua file using this command. In my case,

$(cat myscript.lua)

was causing an error. Saying that "$" is an unknown character.

redis-cli -x script load < myscript.lua

worked for me :)

Endstopped answered 10/7, 2021 at 20:35 Comment(0)
S
1

This is not the same as stored procedures in RDBMS. These loaded scripts are not stored by redis server, they are just cached. so once server restarted, loaded scripts will be gone.

2 possible ways:

You provide the full text of the script for the first execution of the script (i.e. EVAL for the first execution) then you can use EVALSHA for all subsequent calls.

EVALSHA returns special error NOSCRIPT: No Matching script, Please Use [EVAL] in case this SHA digest is invalid so the client can always optimistically send EVALSHA under the hood even when the client actually send EVAL. if NOSCRIPT returned, EVAL will be used instead.

You can use SCRIPT EXISTS and load the script using SCRIPT LOAD in case it doesn't exist.

Check whether script exists:

SCRIPT EXISTS sha1 sha2 ... shaN

Load script:

SCRIPT LOAD script

Or code of the application (including Lua scripts) is managed on application side and you send script everytime you need to execute it if it is small text, in this case you do not need to configure or do anything in Redis side. This is very useful in the context of a distributed environment and with Redis cluster.

A third approach where you may want to change the behavior by adding custom startup scripts in linux where you start redis server and then load all of your scripts there however your app code still won't know anything about these SHA hashes but I don't like this approach with also difficulties in distributed environments.

More Info:

Silicify answered 10/5, 2019 at 19:55 Comment(0)
U
0

Welcome to the future! Redis version 7 has FUNCTIONS which accomplish this:

https://redis.io/docs/manual/programmability/functions-intro/

Ulm answered 16/12, 2022 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.