为了避开带宽问题和上面的问题,redis实现了eva lSHA命令。 eva lSHA works exactly like eva l, but instead of having a script as the first argument it has the SHA1 digest of a script. The behavior is the following:
eva lSHA酷似eva l,但它不是以一个脚本作为第一个参数,它的第一个参数脚本是SHA1摘要。它的行为如下:
If the server still remembers a script with a matching SHA1 digest, the script is executed.
如果服务器记得这个脚本的SHA1摘要,脚本就会被执行。
If the server does not remember a script with this SHA1 digest, a special error is returned telling the client to use eva l instead.
如果服务器不记得这个脚本的SHA1摘要,将返回一个提示使用eva l代替的错误。 Example:例如
> set foo bar
OK
> eva l "return redis.call('get','foo')" 0
"bar"
> eva lsha 6b1bf486c81ceb7edf3c093f4c48582e38c0e791 0
"bar"
> eva lsha ffffffffffffffffffffffffffffffffffffffff 0
(error) `NOSCRIPT` No matching script. Please use [eva l](/commands/eva l). The client library implementation can always optimistically send eva lSHA under the hood even when the client actually calls eva l, in the hope the script was already seen by the server. If the NOSCRIPT error is returned eva l will be used instea
客户端可以乐观地这样实现,在发生eva l命令前可以认为eva l脚本已经被服务器知道了,所以发送eva lSHA。如果返回NOSCRIPT 的错误在使用eva l命令。 Passing keys and arguments as additional eva l arguments is also very useful in this context as the script string remains constant and can be efficiently cached by Redis.
因为脚本字符串保持不变,并且可以通过Redis有效缓存起来,那么通eva lSHA发eva l的key参数和附加参数也是非常有用的。
?
Script cache semantics 缓存脚本的意义
Executed scripts are guaranteed to be in the script cache of a given execution of a Redis instance forever. This means that if an eva l is performed against a Redis instance all the subsequent eva lSHA calls will succeed.执行的脚本都保证在Redis的实例中永远缓存。意思是,在eva l执行之后的脚本,那么接着使用eva lSHA命令都能成功调用执行。 The reason why scripts can be cached for long time is that it is unlikely for a well written application to have enough different scripts to cause memory problems. Every script is conceptually like the implementation of a new command, and even a large application will likely have just a few hundred of them. Even if the application is modified many times and scripts will change, the memory used is negligible.
脚本缓存很长的时间是不太可能的,因为一个好的写应用有很多不同的脚本,脚本多了就会引起内存问题。每一个脚本的概念其实就是实现几个命令,甚至一个大的应用可能一个脚本有几百个命令。尽管应用有时会修改并且脚本会改变,但是减少的内存是微不足道的。 The only way to flush the script cache is by explicitly calling the SCRIPT FLUSHcommand, which will completely flush the scripts cache removing all the scripts executed so far.
唯一清除脚本缓存的方法是明确地调用SCRIPT FLUSH命令,这个命令将完全删除到目前为止所有缓存的脚本。 This is usually needed only when the instance is going to be instantiated for another customer or application in a cloud environment.
在一个实例被用在在集群中或者在云环境中,初始化时通常都需要这样做。 Also, as already mentioned, restarting a Redis instance flushes the script cache, which is not persistent. However from the point of view of the client there are only two ways to make sure a Redis instance was not restarted between two different commands.
另外,如前所述,重启Redis将清除scipt,因为它不是持久化的。对应客户端来说,有两种方式使用两个命令可以确保Redis没有重启。
The connection we have with the server is persistent and was never closed so far. 客户端到目前为止一直和服务器连接着。
The client explicitly checks the runid field in the INFO command in order to make sure the server was not restarted and is still the same process. 执行INFO命令检查runid确保服务器没