指令碼

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);
}
  • 命令式

  • 反應式

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 應為 LongBooleanList 或反序列化的值類型之一。如果腳本傳回可拋棄的狀態(特別是 OK),則也可以為 null

在應用程式上下文中配置 DefaultRedisScript 的單一實例是理想的,以避免在每次腳本運行時重新計算腳本的 SHA1。

上面的 checkAndSet 方法接著運行腳本。腳本可以在 SessionCallback 中作為交易或管線的一部分運行。有關更多資訊,請參閱「Redis 交易」和「管線化」。

Spring Data Redis 提供的腳本支援還允許您使用 Spring Task 和 Scheduler 抽象排程定期運行 Redis 腳本。有關更多詳細資訊,請參閱 Spring Framework 文件。