【问题标题】:How to properly load a Lua script in StackExchange.Redis?如何在 StackExchange.Redis 中正确加载 Lua 脚本?
【发布时间】:2020-09-29 17:45:07
【问题描述】:

StackExchange.Redis docs for scripting 中,它说可以使用 LoadedLuaScript 来避免在每次评估时将 Lua 脚本重新传输到 redis。然后给出了将脚本加载到服务器中的示例。我认为不应该每次调用脚本时都这样做,那么脚本应该加载到哪里?

如果redis服务器重启,脚本是不持久的,那么应该如何处理呢?是否应该在 ConnectionMultiplexer 的 ConnectionRestored 事件中加载它们?大概您需要将它们存储在 ConcurrentDictionary 中?

【问题讨论】:

  • 使用SCRIPT LOAD 命令将脚本加载到redis 本身。此命令返回 sha1 哈希,因此此哈希可以与 EVALSHA 命令一起使用以调用此脚本。事实上,这个脚本可以被任何人加载,你的应用程序可以只使用这个哈希。
  • 谢谢,但我知道这些信息。问题是关于何时以及如何运行 SCRIPT LOAD 命令。您可以在应用启动时执行此操作 - 但如果重新启动 redis 会发生什么?
  • 来自文档The script is guaranteed to stay in the script cache forever。基本逻辑就是使用 EVALSHA,如果出现NOSCRIPT 错误调用 SCRIPT LOAD 并重试

标签: lua stackexchange.redis


【解决方案1】:

StackExchange.Redis 在内部处理 Lua 脚本缓存。通常你不必关心手动加载 Lua 脚本到 redis。

StackExchange.Redis 在第一次调用“ScriptEvaluate”时自动将 Lua 脚本传输到 redis。对于同一脚本的进一步调用,仅使用哈希:

var prepared = LuaScript.Prepare(script);
prepared.Evaluate(someDb); // loads the script to redis and calls it

var prepared2 = LuaScript.Prepare(script);
prepared2.Evaluate(someDb); // calls the script by it's hash

LoadedLuaScript 可能对加载而不执行等边缘情况很有用。

我还澄清了official doku

背景信息

库尝试通过它的哈希调用脚本,如果脚本丢失,它会收到 NOSCRIPT 错误,然后传输脚本。

请参阅https://github.com/StackExchange/StackExchange.Redis/blob/main/src/StackExchange.Redis/RedisDatabase.cs 中的 ScriptEvalMessage:GetMessages

官方 StackExchange.Redis github repo 中也讨论和解释了该行为:

【讨论】:

  • 请解释您的答案,以便下一位用户知道为什么此解决方案对您有效。另外,总结一下您的答案,以防链接将来停止工作。
  • 感谢@Elydasian 的反馈。我扩展了答案,
猜你喜欢
  • 2015-10-10
  • 2015-11-13
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
相关资源
最近更新 更多