Redis 后台内存分配问题影响 Lua 脚本运行
2017-2-27 23:35:14
收藏:0
阅读:67
评论:1
我最近在一个 Django 应用中添加了一些 Lua 脚本(用于与 Redis 后端进行交互)。在生产环境中(但不是在开发环境中),设置最终会给我以下错误:
Error running script (call to f_8c07b227bc796743f66bad8dbe75a5bf8fcc8cd6): @user_script:2: @user_script: 2: -MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
发生这种情况时,如果我查看 Redis 日志,就会看到 can't save in background: fork: Cannot allocate memory。
我知道发生了什么。我的问题是,为什么在无法为后台保存分配内存时,Redis 仍然正常运行,但 Lua 脚本会崩溃?有方法可以避免这种情况吗?
FYI,以下是我的 lua_scripts.py 模块的布局:
import redis
from location import REDLOC2 #location of relevant unix socket
my_server = redis.StrictRedis(unix_socket_path=REDLOC2)
# Get recent
lualatestlogins = """
local l = redis.call('ZRANGEBYSCORE', KEYS[1], ARGV[1]-600, '+inf') -- returns key:value pairs
local c = {}
for _, v in pairs(l) do
local p = v:find(':')
local i = v:sub(1,p-1)
c[#c+1] = i
end
return c"""
getlatestlogins = my_server.register_script(lualatestlogins)
# Evict old
luacleanselogins = """
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', '(' .. ARGV[1]-600)"""
cleanselogins = my_server.register_script(luacleanselogins)
# -- Store new
luastorelogin = """
redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2] .. ':' .. ARGV[3])
redis.call('SET',KEYS[2],ARGV[3])
redis.call('EXPIRE',KEYS[2],600)"""
storelogin = my_server.register_script(luastorelogin)
# Retrieve collisions
luaretrieveclones = """
local q = redis.call('GET',KEYS[2])
if q == nil or q == '' then
return nil
else
local l = redis.call('ZRANGEBYSCORE', KEYS[1], ARGV[1]-600, '+inf')
local c = {}
for _, v in pairs(l) do
local p = v:find(':')
local i = v:sub(1,p-1)
local n = v:sub(p+1)
if n == q then
c[#c+1] = i
end
end
return c
end"""
retrieveclones = my_server.register_script(luaretrieveclones)
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

错误提示告诉你一切:禁止修改数据集的命令已被禁用。
当 Redis 尝试创建一个新进程进行后台保存时,由于内存不足而失败。在这种情况下,Redis 禁用对数据库的任何更新操作。否则,内存中的数据和磁盘上的数据将不一致。
Redis 仍然可以服务只读请求,并拒绝任何可能修改数据库的请求。
当你的 Lua 脚本尝试修改数据库时,例如
redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2] .. ':' .. ARGV[3]),会失败。你应该监视这种错误,并将 Redis 移动到一个具有更多内存的新机器以进行扩展,或者使用 Redis 集群进行扩展。
在你的 Lua 脚本中,使用
redis.pcall而不是redis.call。如果redis.call失败,整个脚本将终止。但是,如果redis.pcall失败,它会捕获错误并返回一个包含错误消息的 Lua 表。你可以检查返回的表来查看你的调用是否成功执行。