指令碼
Redis 2.6 及更高版本提供透過 eval 和 evalsha 命令執行 Lua 腳本的支援。Spring Data Redis 為執行腳本提供高階抽象,可處理序列化並自動使用 Redis 腳本快取。
腳本可以透過呼叫 RedisTemplate
和 ReactiveRedisTemplate
的 execute
方法來執行。兩者都使用可配置的 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);
}
-
命令式
-
反應式
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);
}
}
public class Example {
@Autowired
ReactiveRedisOperations<String, String> redisOperations;
@Autowired
RedisScript<Boolean> script;
public Flux<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 文件。