You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Redis Stack执行Lua脚本报错:尝试修改只读表

解决Redis Lua脚本"Attempt to modify a readonly table"错误

问题原因

你遇到的错误是因为Lua脚本中未使用local声明全局作用域的变量。Redis的Lua执行环境为了保证脚本隔离性,将全局表设置为只读状态,直接赋值全局变量会触发这个只读限制错误。

看你的脚本第一行:

tokens_key = KEYS[1]

这里没有添加local关键字,导致tokens_key被当作全局变量处理,试图写入只读的全局表,从而抛出错误。

解决方法

给所有全局作用域的变量加上local关键字,将其声明为局部变量即可解决。修改后的完整脚本如下:

local tokens_key = KEYS[1]
local timestamp_key = KEYS[2]

local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])

local fill_time = capacity/rate
local ttl = math.floor(fill_time*2)

local last_tokens = tonumber(redis.pcall("get", tokens_key))
if last_tokens == nil then
  last_tokens = capacity
end

local last_refreshed = tonumber(redis.pcall("get", timestamp_key))
if last_refreshed == nil then
  last_refreshed = 0
end

local delta = math.max(0, now-last_refreshed)
local filled_tokens = math.min(capacity, last_tokens+(delta*rate))
local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
if allowed then
  new_tokens = filled_tokens - requested
end

redis.pcall("setex", tokens_key, ttl, new_tokens)
redis.pcall("setex", timestamp_key, ttl, now)

return { allowed, new_tokens }

补充说明

Redis限制全局变量修改,是为了避免不同脚本之间的变量污染,保证每个脚本的执行环境完全隔离。所有不需要全局共享的变量都应该用local声明为局部变量,这不仅能避免此类错误,还能提升脚本的执行效率。

内容的提问来源于stack exchange,提问作者Pratham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:09:25