跳到主要内容

脚本编写

DeepSeek V3 中英对照 Scripting

Redis 2.6 及更高版本提供了通过 evalevalsha 命令运行 Lua 脚本的支持。Spring Data Redis 为运行脚本提供了一个高级抽象,它处理序列化并自动使用 Redis 脚本缓存。

可以通过调用 RedisTemplateReactiveRedisTemplateexecute 方法来运行脚本。两者都使用可配置的 ScriptExecutor(或 ReactiveScriptExecutor)来运行提供的脚本。默认情况下,ScriptExecutor(或 ReactiveScriptExecutor)负责序列化提供的键和参数,并反序列化脚本结果。这是通过模板的键和值序列化器来完成的。还有一个额外的重载方法,允许你为脚本参数和结果传递自定义的序列化器。

默认的 ScriptExecutor 通过获取脚本的 SHA1 并尝试首先运行 evalsha 来优化性能,如果脚本尚未存在于 Redis 脚本缓存中,则回退到 eval

以下示例通过使用 Lua 脚本运行了一个常见的“检查并设置”场景。这是一个 Redis 脚本的理想用例,因为它需要原子性地运行一组命令,并且一个命令的行为会受到另一个命令结果的影响。

@Bean
public RedisScript<Boolean> script() {

ScriptSource scriptSource = new ResourceScriptSource(new ClassPathResource("META-INF/scripts/checkandset.lua"));
return RedisScript.of(scriptSource, Boolean.class);
}
java
public class Example {

@Autowired
RedisOperations<String, String> redisOperations;

@Autowired
RedisScript<Boolean> script;

public boolean checkAndSet(String expectedValue, String newValue) {
return redisOperations.execute(script, List.of("key"), expectedValue, newValue);
}
}
java
-- checkandset.lua
local current = redis.call('GET', KEYS[1])
if current == ARGV[1]
then redis.call('SET', KEYS[1], ARGV[2])
return true
end
return false
lua

前面的代码配置了一个指向名为 checkandset.lua 文件的 RedisScript,该文件预计返回一个布尔值。脚本的 resultType 应为 LongBooleanList 或反序列化的值类型之一。如果脚本返回一个丢弃状态(特别是 OK),它也可以是 null

提示

在应用程序上下文中配置单个 DefaultRedisScript 实例是理想的做法,这样可以避免在每次脚本运行时重新计算脚本的 SHA1 值。

上面的 checkAndSet 方法随后会运行脚本。脚本可以在 SessionCallback 中作为事务或管道的一部分运行。有关更多信息,请参阅“Redis 事务”和“管道”。

Spring Data Redis 提供的脚本支持还允许您使用 Spring 任务和调度器抽象来安排 Redis 脚本定期运行。有关更多详细信息,请参阅 Spring Framework 文档。