Introduction
EVAL and EVALSHA are used to evaluate scripts using the Lua interpreter built into Redis starting from version 2.6.0.
Related commands
- EVAL
- EVALSHA
为什么要用Lua?
- 减少网络开销(批量执行命令):不使用 Lua 的代码需要向 Redis 发送多次请求, 而脚本只需一次即可, 减少网络传输;
- 原子操作:Redis 将整个脚本作为一个原子执行,无需担心并发,也就无需事务;
- 复用:脚本会永久保存 Redis 中,其他客户端可继续使用。
Practice
EVAL
EVAL script numkeys key [key …] arg [arg …]
1 | EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second |
Evalsha
1 | script load "return 'hello world'" |
IP Access Limitation
1 | local access = redis.call('incr', KEYS[1]) |
Endless Loop
1 | eval 'while(true) do end' 0 |
Attention
redis.call() 与 redis.pcall() 的区别
两者唯一区别在于它们对错误处理的不同:
当 redis.call() 在执行命令的过程中发生错误时,脚本会停止执行,并返回一个脚本错误,错误的输出信息会说明错误造成的原因:
1
2EVAL "return redis.call('SADD','evalShell','a')" 0
(error) ERR Error running script (call to f_e17faafbc130014cebb229b71e0148b1f8f52389): @user_script:1: WRONGTYPE Operation against a key holding the wrong kind of valueredis.pcall() 出错时并不引发(raise)错误,而是返回一个带 err 域的 Lua 表(table),用于表示错误(这样与命令行客户端直接操作返回相同):
1
2EVAL "return redis.pcall('SADD','evalShell','a')" 0
(error) WRONGTYPE Operation against a key holding the wrong kind of value