本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Lua 指令碼
Valkey 和 Redis OSS 支援超過 200 個命令,包括執行 Lua 指令碼的命令。不過,在 Lua 指令碼方面,有幾個陷阱可能會影響 Valkey 或 Redis OSS 的記憶體和可用性。
未參數化的 Lua 指令碼
每個 Lua 指令碼都會在執行之前快取在 Valkey 或 Redis OSS 伺服器上。無參數 Lua 指令碼是唯一的,這可能會導致 Valkey 或 Redis OSS 伺服器存放大量 Lua 指令碼並耗用更多記憶體。為了緩解這種情況,務必確保所有 Lua 指令碼皆參數化,並且在需要時定期執行 SCRIPT FLUSH 來清除快取的 Lua 指令碼。
另請注意,必須提供金鑰。如果未提供 KEY 參數的值,指令碼將會失敗。例如,這將無法運作:
serverless-test-lst4hg.serverless.use1.cache.amazonaws.com:6379> eval 'return "Hello World"' 0 (error) ERR Lua scripts without any input keys are not supported.
這將有效:
serverless-test-lst4hg.serverless.use1.cache.amazonaws.com:6379> eval 'return redis.call("get", KEYS[1])' 1 mykey-2 "myvalue-2"
以下範例說明如何使用參數化指令碼。首先將示範非參數化的方法來產生三個不同的已快取 Lua 指令碼,這是不建議的方法:
eval "return redis.call('set','key1','1')" 0 eval "return redis.call('set','key2','2')" 0 eval "return redis.call('set','key3','3')" 0
建議改用下列模式來建立可接受所傳遞參數的單一指令碼:
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key1 1 eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key2 2 eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key3 3
長時間執行的 Lua 指令碼
Lua 指令碼可以以原子方式執行多個命令,因此完成時間可能比一般 Valkey 或 Redis OSS 命令更長。如果 Lua 指令碼只執行唯獨操作,就可以讓它中途停止執行。然而,一旦 Lua 指令碼執行寫入操作,就無法讓它終止,而必須執行到完成為止。長時間執行且正在變動的 Lua 指令碼可能會導致 Valkey 或 Redis OSS 伺服器長時間沒有回應。為了解決此問題,請避免長時間執行的 Lua 指令碼,並且在生產前環境中測試指令碼。
具有隱匿寫入的 Lua 指令碼
有幾種方式可以讓 Lua 指令碼繼續將新資料寫入 Valkey 或 Redis OSS,即使 Valkey 或 Redis OSS 超過 maxmemory
:
指令碼會在 Valkey 或 Redis OSS 伺服器低於 時啟動
maxmemory
,並在 內包含多個寫入操作指令碼的第一個寫入命令不會耗用記憶體 (例如 DEL),但後續更多的寫入操作則會耗用記憶體
您可以在 以外的 Valkey 或 Redis OSS 伺服器上設定適當的移出政策,以緩解此問題
noeviction
。這可讓 Redis OSS 在 Lua 指令碼之間移出項目並釋放記憶體。