Redis中的Lua脚本超时
Redis 的指令執行本身是單線程的,這個線程還要執行客戶端的Lua 腳本,如果Lua腳本執行超時或者陷入了死循環,是不是沒有辦法為客戶端提供服務了呢?
eval 'while(true) do end' 0為了防止某個腳本執行時間過長導致Redis 無法提供服務, Redis 提供了lua-time-limit 參數限制腳本的最長運行時間,默認為5 秒鐘。
lua-time-limit 5000(redis.conf 配置文件中)
當腳本運行時間超過這一限制后,Redis 將開始接受其他命令但不會執行(以確保腳本的原子性,因為此時腳本并沒有被終止),而是會返回“BUSY”錯誤。
Redis 提供了一個script kill 的命令來中止腳本的執行。新開一個客戶端:
script kill如果當前執行的Lua 腳本對Redis 的數據進行了修改(SET、DEL 等),那么通過script kill 命令是不能終止腳本運行的。
127.0.0.1:6379> eval "redis.call('set','gupao','666') while true do end" 0因為要保證腳本運行的原子性,如果腳本執行了一部分終止,那就違背了腳本原子性的要求。最終要保證腳本要么都執行,要么都不執行。
127.0.0.1:6379> script kill (error) UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.遇到這種情況,只能通過shutdown nosave 命令來強行終止redis。
shutdown nosave 和shutdown 的區別在于shutdown nosave 不會進行持久化操作,意味著發生在上一次快照后的數據庫修改都會丟失。
總結:如果我們有一些特殊的需求,可以用Lua 來實現,但是要注意那些耗時的操作。
?
總結
以上是生活随笔為你收集整理的Redis中的Lua脚本超时的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis中缓存Lua 脚本
- 下一篇: Redis 到底有多快?