是否可以在redis中调用其他lua脚本中定义的lua函数? [英] is it possible to call lua functions defined in other lua scripts in redis?

查看:458
本文介绍了是否可以在redis中调用其他lua脚本中定义的lua函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图声明一个没有local关键字的函数,然后从其他脚本调用该函数,但是当我运行该命令时,它给了我一个错误.

I have tried to declare a function without the local keyword and then call that function from anther script but it gives me an error when I run the command.

test = function ()    
    return 'test'
end



# from some other script
test()

我不敢相信我对此仍然没有答案.我将提供我的设置的更多详细信息.

I can't believe I still have no answer to this. I'll include more details of my setup.

我正在使用带有redis-scripto包的node来将脚本加载到redis中.这是一个例子.

I am using node with the redis-scripto package to load the scripts into redis. Here is an example.

var Scripto = require('redis-scripto');
var scriptManager = new Scripto(redis);

scriptManager.loadFromDir('./lua_scripts');

var keys    = [key1, key2];
var values  = [val];

scriptManager.run('run_function', keys, values, function(err, result) {
console.log(err, result)
})

还有lua脚本.

-- ./lua_scripts/dict_2_bulk.lua

-- turns a dictionary table into a bulk reply table
dict2bulk = function (dict)
    local result = {}
    for k, v in pairs(dict) do
        table.insert(result, k)
        table.insert(result, v)
    end
    return result
end


-- run_function.lua 

return dict2bulk({ test=1 })

引发以下错误.

[Error: ERR Error running script (call to f_d06f7fd783cc537d535ec59228a18f70fccde663): @enable_strict_lua:14: user_script:1: Script attempted to access unexisting global variable 'dict2bulk' ] undefined

推荐答案

重要提示:请参见下面的约西亚的答案.我的答案竟然是错误或至少是不完整.当然,这让我感到非常高兴,这使Redis更加灵活.

Important Notice: See Josiah's answer below. My answer turns out to be wrong or at the least incomplete. Which makes me very happy ofcourse, it makes Redis all the more flexible.

我的答案不正确/不完整:

我非常确定这是不可能的.不允许使用全局变量(请阅读 docs ),脚本本身会获得本地和临时变量范围由Redis Lua引擎提供.

I'm quite sure this is not possible. You are not allowed to use global variables (read the docs ), and the script itself gets a local and temporary scope by the Redis Lua engine.

Lua函数在执行写操作时会在幕后自动设置正在写入"标志.这将启动一个事务.如果您级联Lua调用,则Redis中的簿记会变得非常麻烦,尤其是当级联在Redis从属服务器上执行时.这就是为什么在Lua脚本中故意不提供EVALEVALSHA作为有效的Redis调用的原因.调用您正在尝试执行的已加载"的Lua函数也是如此.如果从服务器在第一个脚本的加载与第二个脚本的exec之间重新启动,将会发生什么情况?

Lua functions automatically set a 'writing' flag behind the scenes if they do any write action. This starts a transaction. If you cascade Lua calls, the bookkeeping in Redis would become very cumbersome, especially when the cascade is executed on a Redis slave. That's why EVAL and EVALSHA are intentionally not made available as valid Redis calls inside a Lua script. Same goes for calling an already 'loaded' Lua function which you are trying to do. What would happen if the slave is rebooted between the load of the first script and the exec of the second script?

我们为克服此限制而采取的措施:

What we do to overcome this limitation:

不使用EVAL,仅使用SCRIPT LOADEVALSHA. 将SHA1存储在Redis哈希集中.

Don't use EVAL, only use SCRIPT LOAD and EVALSHA. Store the SHA1 inside a redis hash set.

我们在版本控制系统中对此进行了自动化,因此已提交的Lua脚本会自动将其SHA1校验和以逻辑名的形式存储在Redis主数据库中的散列集中.客户端不能使用EVAL(在从属服务器上;我们在配置中禁用了EVAL + LOAD).但是客户端可以要求SHA1进行下一步.几乎我们所有的Lua函数都为下一次调用返回SHA1.

We automated this in our versioning system, so a committed Lua script automatically gets it's SHA1 checksum stored in the Redis master, in a hash set, with a logical name. The clients can't use EVAL (on a slave; we disabled EVAL+LOAD in config). But the client can ask for the SHA1 for the next step. Almost all our Lua functions return a SHA1 for the next call.

希望这对您有帮助,TW

Hope this helps, TW

这篇关于是否可以在redis中调用其他lua脚本中定义的lua函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆