Lua 脚本 ===

Lua 脚本 | 管道 | 集群模式


默认连接中的 Lua 脚本#

redis-py 支持 EVAL、EVALSHA 和 SCRIPT 命令。但是,在实际应用场景中,这些命令存在一些边缘情况,导致使用起来很繁琐。因此,redis-py 公开了 Script 对象,使脚本的使用变得更加容易。(Redis 集群对脚本的支持有限。)

要创建 Script 实例,请在客户端实例上使用 register_script 函数,并将 Lua 代码作为第一个参数传递。register_script 返回一个 Script 实例,您可以在整个代码中使用它。

以下简单的 Lua 脚本接受两个参数:键的名称和乘数值。该脚本获取存储在键中的值,将其乘以乘数值,并返回结果。

>>> r = redis.Redis()
>>> lua = """
... local value = redis.call('GET', KEYS[1])
... value = tonumber(value)
... return value * ARGV[1]"""
>>> multiply = r.register_script(lua)

multiply 现在是一个 Script 实例,可以通过像函数一样调用它来调用。Script 实例接受以下可选参数

  • keys:脚本将访问的键名列表。这将成为 Lua 中的 KEYS 列表。

  • args:参数值列表。这将成为 Lua 中的 ARGV 列表。

  • client:将调用脚本的 redis-py Client 或 Pipeline 实例。如果未指定 client,则将使用最初创建 Script 实例的客户端(即调用 register_script 的客户端)。

继续上面的例子

>>> r.set('foo', 2)
>>> multiply(keys=['foo'], args=[5])
10

键“foo”的值设置为 2。当调用 multiply 时,将“foo”键与乘数值 5 一起传递给脚本。Lua 执行脚本并返回结果 10。

可以使用不同的客户端实例(甚至指向完全不同的 Redis 服务器的客户端实例)执行 Script 实例。

>>> r2 = redis.Redis('redis2.example.com')
>>> r2.set('foo', 3)
>>> multiply(keys=['foo'], args=[5], client=r2)
15

Script 对象确保 Lua 脚本加载到 Redis 的脚本缓存中。如果发生 NOSCRIPT 错误,它将加载脚本并重试执行。

管道#

Script 对象也可以在管道中使用。调用脚本时,应将管道实例作为 client 参数传递。会小心确保在管道执行之前将脚本注册到 Redis 的脚本缓存中。

>>> pipe = r.pipeline()
>>> pipe.set('foo', 5)
>>> multiply(keys=['foo'], args=[5], client=pipe)
>>> pipe.execute()
[True, 25]

集群模式#

集群模式对 lua 脚本的支持有限。

以下命令受支持,但有注意事项: - EVALEVALSHA:命令将发送到相关节点,具体取决于键(即在 EVAL "<script>" num_keys key_1 ... key_n ... 中)。键必须都在同一个节点上。如果脚本需要 0 个键,则命令将发送到随机(主)节点。 - SCRIPT EXISTS:命令将发送到所有主节点。结果是一个布尔值列表,对应于输入的 SHA 哈希值。每个布尔值都是“脚本是否在每个节点上存在”的 AND。换句话说,每个布尔值在脚本存在于所有节点上时为 True。 - SCRIPT FLUSH:命令将发送到所有主节点。结果是所有节点响应的 bool AND。 - SCRIPT LOAD:命令将发送到所有主节点。结果是 SHA1 摘要。

以下命令不支持: - EVAL_RO - EVALSHA_RO

在集群模式下,管道内使用脚本**不支持**。