SCRIPT LOAD和EVALSHA:缓存并执行脚本
在定义脚本之后,程序通常会重复地执行脚本。一个简单的脚本可能 只有几十到上百字节,而一个复杂的脚本可能会有数百字节甚至数千 字节,如果客户端每次执行脚本都需要将相同的脚本重新发送一次, 这对于宝贵的网络带宽来说无疑是一种浪费。
为了解决上述问题,Redis提供了Lua脚本缓存功能,这一功能允许用 户将给定的Lua脚本缓存在服务器中,然后根据Lua脚本的SHA1校验和 直接调用脚本,从而避免了需要重复发送相同脚本的麻烦。
命令SCRIPT LOAD可以将用户给定的脚本缓存在服务器中,并返回脚本 对应的SHA1校验和作为结果:
SCRIPT LOAD script
作为例子,以下代码将两个脚本载入了脚本缓存中:
redis> SCRIPT LOAD "return 'hello world'"
"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"
redis> SCRIPT LOAD "redis.call('SET', KEYS[1], ARGV[1]); return redis.call
('GET', KEYS[1])"
"18d788194860a281b19910d462b1e96dabf3c984"
在此之后,用户就可以通过EVALSHA命令来执行已被缓存的脚本了:
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
除了第一个参数接受的是Lua脚本对应的SHA1校验和而不是脚本本身之 外,EVALSHA命令的其他参数与EVAL命令的参数都是相同的。
作为例子,以下代码展示了如何使用EVALSHA执行之前缓存的两个脚 本:
redis> EVALSHA "5332031c6b470dc5a0dd9b4bf2030dea6d65de91" 0
"hello world"
redis> EVALSHA "18d788194860a281b19910d462b1e96dabf3c984" 1 "msg" "Ciao!"
"Ciao!"
除了SCRIPT LOAD之外,EVAL命令在执行完脚本之后也会把被执行的脚 本缓存起来,以供之后使用。
比如在执行完以下EVAL命令之后,脚本"return 10086"就会被缓存起来:
redis> EVAL "return 10086" 0
(integer) 10086
在此之后,我们同样可以通过脚本的SHA1校验和来再次执行该脚本:
redis> EVALSHA "a9b6689bf0d2962188a5fb8f2502e8de5a19fc26" 0
(integer) 10086
不过由于EVAL命令并不会返回给定脚本的SHA1校验和,所以用户在调 用EVALSHA命令之前,必须事先通过其他方法计算出脚本的SHA1校验 和。在一般情况下,直接使用SCRIPT LOAD和EVALSHA会更方便一些。
通过Lua脚本缓存,我们可以将需要重复执行的Lua脚本缓存在服务器 中,然后通过EVALSHA命令来执行已缓存的脚本,从而将执行Lua脚本 所需耗费的网络带宽降至最低。