StackExchange.Redis 系列 11:Scripting 说明

  • 本系列博文是“伪”官方文档翻译,并非完全将官方文档进行翻译,而是我在查阅、测试原始文档并转换为自己东西后进行的“准”翻译。

  • 原始文档见此:https://stackexchange.github.io/StackExchange.Redis/

  • 本系列本博文基于 redis 5.0.6,系列中部分博文跟官方文档有出入,有不同见解 / 说明不当的地方,还请大家不吝拍砖。

StackExchange.Redis 库中提供了以下几个接口来让你执行 LUA 基本脚本:

  • IServer.ScriptLoad(Async)

  • IServer.ScriptExists(Async)

  • IServer.ScriptFlush(Async)

  • IDatabase.ScriptEvaluate

  • IDatabaseAsync.ScriptEvaluateAsync

要执行复杂脚本的话,可以通过 LuaScript 类来进行构建。

LuaScript 示例

1
2
3
4
5
6
7
8
9
const string Script = "redis.call('set', @key, @value)";

using (ConnectionMultiplexer conn = /* init code */)
{
var db = conn.GetDatabase(0);

var prepared = LuaScript.Prepare(Script);
db.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 });
}
  • LuaScript 类会将脚本中 @myvar 这样形式的变量重写为 Redis 所需的 ARGV[someIndex] 这样的形式,如果传递的参数类型是 RedisKey,则会自动转换为 KEYS 集合后进行发送。

任何对外的类成员字段或者属性,只要跟LUA脚本中的“@前缀”变量,那么在调用 Evaluate 方法的时候,都可以作为该方法的调用参数。支持的类型如下:

  • int(?)

  • long(?)

  • double(?)

  • string

  • byte[]

  • bool(?)

  • RedisKey

  • RedisValue

这里可以简单理解为跟 'SqlHelper’中的参数化调用是一样的,具体可见下方示例

1
2
3
4
5
6
7
8
9
10
11
12
const string Script = "redis.call('set', @key, @value)"; 

using (ConnectionMultiplexer conn = /* init code */)
{
var db = conn.GetDatabase(0);
var server = conn.GetServer(/* appropriate parameters*/);

var prepared = LuaScript.Prepare(Script);
var loaded = prepared.Load(server);
//下方匿名对象中的 key 和 value 属性,会替换上方字符串常量中的 @key 和 @value
loaded.Evaluate(db, new { key = (RedisKey)"mykey", value = 123 });
}
  • 以上示例中,为了避免每次调用 Evaluate 的时候都将 LUA 脚本重新传输到 Redis 服务,使用 LuaScript.Load(IServer) 可以把 LuaScript 对象转换为 LoadedLuaScript,最终 EVALSHA 会对 LoadedLuaScript 进行 Evaluate,并通过哈希进行引用。

  • 所有 LuaScript 和 LoadedLuaScript 的方法都提供了异步版本。