跳到主要内容
版本:4.1.1

脚本

Doubao 中英对照 Scripting

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

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

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

下例使用一个 Lua 脚本运行常见的“检查并设置”(check-and-set)场景。这是 Redis 脚本的理想用例,因为它要求原子地运行一组命令,且一个命令的行为会受到另一个命令结果的影响。

@Bean
public RedisScript<Boolean> script() {

ScriptSource scriptSource = new ResourceScriptSource(new ClassPathResource("META-INF/scripts/checkandset.lua"));
return RedisScript.of(scriptSource, Boolean.class);
}
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);
}
}
-- 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

上述代码配置了一个指向名为 checkandset.lua 文件的 RedisScript,该脚本预期返回一个布尔值。脚本的 resultType 应为 Long、Boolean、List 之一,或一个反序列化后的值类型。如果脚本返回的是一次性状态(具体为 OK),它也可以是 null。

提示

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

上面的 checkAndSet 方法随后会运行这些脚本。脚本可以在 SessionCallback 中作为事务或流水线的一部分运行。更多信息请参见“Redis 事务”和“流水线操作”。

Spring Data Redis 提供的脚本支持还让你可以使用 Spring Task 和 Scheduler 抽象来安排 Redis 脚本定期运行。更多信息请参见 Spring Framework 文档。