使用StackExchange.Redis时,我们需要缓存已加载的脚本吗?
我正在创建一个主要用于非 Web 环境的库,通过 StackExchange.Redis 利用 Lua 脚本。
当使用 StackExchange.Redis 时,我们是否应该为每个 Evaluate 调用加载 Lua 脚本,例如:
var prepped = LuaScript.Prepare(_someScript);
var loaded = prepped.Load(someServer);
loaded.Evaluate(someDb);
或者我们应该加载一次,然后在给定进程中每次评估时重用 LoadedLuaScript 实例?
为了实现更好的性能,Lua 脚本可以被加载到 Redis 中,然后通过它们的哈希值进行调用。加载过程是可选的,并且只需要执行一次以获得性能提升。
使用 StackExchange.Redis,您不需要显式地使用 Load 方法。更容易让 StackExchange.Redis 处理缓存。LuaScript 类会在第一次调用 ScriptEvaluate 时自动将 Lua 脚本传输到 Redis。对于同一脚本的进一步调用,只使用哈希值:
var prepared = LuaScript.Prepare(script);
prepared.Evaluate(someDb); // 将脚本加载到 Redis 并调用它
var prepared2 = LuaScript.Prepare(script);
prepared2.Evaluate(someDb); // 通过哈希值调用脚本
无法评论,但我想补充一下 @ChriZ 的回答,
LuaScript.Evaluate 看起来可能会使用缓存,通过查看 RedisDatabase.cs->GetMessages(没有检查)。。但是。。
根据Evaluate代码,它似乎做了一些肮脏的哈希正则表达式检查(ScriptLoadProcessor.IsSHA1)和很多其他检查,在我看来并不是很有效率。。
此外,如果您进入 LuaScript.cs,它明确写着:
与 LuaScript 不同,LoadedLuaScript 向 Redis 发送其可执行脚本的哈希值,而不是在每次调用时传递整个脚本。 这要求在使用脚本之前将其加载到 Redis 中。 要创建 LoadedLuaScript,请先通过 LuaScript.Prepare(string)创建 LuaScript,然后在返回的 LuaScript 上调用 Load(IServer,CommandFlags)。
如果我错了,请纠正我...
- 如何将两个不同的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 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
脚本应该在启动时加载一次,并保留 LoadedLuaScript 实例以供需要时评估。StackExchange.Redis 不会在任何地方缓存 LoadedLuaScripts,因此如果您每次调用都要执行预处理和加载过程,那么您需要做的就是让 StackExchange.Redis 将脚本传输到 Redis,在那里对其进行哈希,Redis 会意识到已经有了它,然后传回哈希。
如果您的进程不经常启动(对于某些频率),即使已在 Redis 中加载了它们,将所有脚本在启动时加载也是合理的,因为这不会导致多个脚本实例被缓存在 Redis 中。您可以将 LoadedLuaScripts 保留在简单的缓存中,例如:
private static readonly string _helloScript = "print(\"Hello World!\")" ; public void LoadScripts(IDatabase db, IServer srv) { var scripts = new Dictionary<string, string> { { "sayHello", _helloScript }, }; foreach (var scriptName in scripts.Keys) { var prepped = LuaScript.Prepare(scripts[scriptName]); _scripts.Add(scriptName, prepped.Load(srv)); } } public void SayHello(IDatabase db) { _scripts["sayHello"].Evaluate(db); }