小编典典

通过一个Redis Lua脚本使用多个DB?

redis

是否可以使一个Redis Lua脚本命中多个数据库?我目前在DB 0中拥有一种类型的信息,而在DB
1中具有另一种类型的信息。我的正常工作流程是基于API调用以及来自DB 0的元信息对DB 1进行更新。
Lua脚本,但无法弄清楚如何打多个数据库。我正在使用redis-py在Python中执行此操作:

lua_script(keys=some_keys,
           args=some_args,
           client=some_client)

由于客户端暗示一个特定的数据库,所以我被困住了。有想法吗?


阅读 918

收藏
2020-06-20

共1个答案

小编典典

将相关数据放入不同的Redis数据库通常是一个错误的想法。与通过键命名约定定义名称空间相比几乎没有好处(没有关于安全性,持久性,过期管理等的额外粒度)。一个主要的缺点是客户端必须手动处理正确数据库的选择,这对于同时针对多个数据库的客户端来说很容易出错。

现在,如果您仍想使用多个数据库,则有一种方法可以使其与redis-py和Lua脚本一起使用。

由于底层线程安全的连接池实现,redis-
py没有为SELECT命令定义包装器(通常用于切换当前数据库)。但是没有什么可以阻止您从Lua脚本调用SELECT的。

考虑以下示例:

$ redis-cli
SELECT 0
SET mykey db0
SELECT 1
SET mykey db1

以下脚本在同一客户端连接的2个数据库中显示mykey的值。

import redis

pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)

lua1 = """
   redis.call("select", ARGV[1])
   return redis.call("get",KEYS[1])
"""
script1 = r.register_script(lua1)

lua2 = """
   redis.call("select", ARGV[1])
   local ret = redis.call("get",KEYS[1])
   redis.call("select", ARGV[2])
   return ret
"""
script2 = r.register_script(lua2)

print r.get("mykey")
print script2( keys=["mykey"], args = [1,0] )
print r.get("mykey"), "ok"
print
print r.get("mykey")
print script1( keys=["mykey"], args = [1] )
print r.get("mykey"), "misleading !!!"

脚本lua1天真:它只是在返回值之前选择一个给定的数据库。它的用法具有误导性,因为执行后,与该连接关联的当前数据库已更改。不要这样

脚本lua2更好。它以目标数据库和当前数据库为参数。它确保在脚本结束之前重新激活当前数据库,以便在连接上应用的下一个命令仍在正确的数据库中运行。不幸的是,在Lua脚本中没有命令来猜测当前数据库,因此客户端必须系统地提供它。请注意,无论发生什么情况(即使出现先前的错误),Lua脚本都必须在最后将当前数据库重置,因此它会使复杂的脚本变得笨拙而笨拙。

2020-06-20