一个Redis Lua脚本使用多个数据库? [英] Use Multiple DBs With One Redis Lua Script?

查看:36
本文介绍了一个Redis Lua脚本使用多个数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个 Redis Lua 脚本是否可以访问多个数据库?我目前在 DB 0 中拥有一种类型的信息,在 DB 1 中拥有另一种类型的信息.我的正常工作流程是根据 API 调用以及来自 DB 0 的元信息对 DB 1 进行更新.我很想将所有事情都放在一起Lua 脚本,但不知道如何命中多个数据库.我正在使用 redis-py 在 Python 中执行此操作:

Is it possible to have one Redis Lua script hit more than one database? I currently have information of one type in DB 0 and information of another type in DB 1. My normal workflow is doing updates on DB 1 based on an API call along with meta information from DB 0. I'd love to do everything in one Lua script, but can't figure out how to hit multiple dbs. I'm doing this in Python using redis-py:

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

由于客户端暗示了一个特定的数据库,我被卡住了.想法?

Since the client implies a specific db, I'm stuck. Ideas?

推荐答案

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

It is usually a wrong idea to put related data in different Redis databases. There is almost no benefit compared to defining namespaces by key naming conventions (no extra granularity regarding security, persistence, expiration management, etc ...). And a major drawback is the clients have to manually handle the selection of the correct database, which is error prone for clients targeting multiple databases at the same time.

现在,如果你仍然想使用多个数据库,有一种方法可以让它与 redis-py 和 Lua 脚本一起工作.

Now, if you still want to use multiple databases, there is a way to make it work with redis-py and Lua scripting.

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

redis-py does not define a wrapper for the SELECT command (normally used to switch the current database), because of the underlying thread-safe connection pool implementation. But nothing prevents you to call SELECT from a Lua script.

考虑以下示例:

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

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

The following script displays the value of mykey in the 2 databases from the same client connection.

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 是幼稚的:它只是在返回值之前选择给定的数据库.它的用法具有误导性,因为在执行后,与连接关联的当前数据库已更改.不要这样做.

Script lua1 is naive: it just selects a given database before returning the value. Its usage is misleading, because after its execution, the current database associated to the connection has changed. Don't do this.

脚本lua2要好得多.它以目标数据库和当前数据库为参数.它确保在脚本结束之前重新激活当前数据库,以便在连接上应用的下一个命令仍然在正确的数据库中运行.遗憾的是,Lua 脚本中没有猜测当前数据库的命令,所以客户端必须系统地提供.请注意,无论发生什么,Lua 脚本都必须在最后重置当前数据库(即使在之前的错误的情况下),因此它会使复杂的脚本变得繁琐和尴尬.

Script lua2 is much better. It takes the target database and the current database as parameters. It makes sure that the current database is reactivated before the end of the script, so that next command applied on the connection still run in the correct database. Unfortunately, there is no command to guess the current database in the Lua script, so the client has to provide it systematically. Please note the Lua script must reset the current database at the end whatever happens (even in case of previous error), so it makes complex scripts cumbersome and awkward.

这篇关于一个Redis Lua脚本使用多个数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆