2013-05-28 34 views
4

是否有可能讓一個Redis Lua腳本碰到多個數據庫?我目前在DB 0中有一種類型的信息,而在DB 1中有另一種類型的信息。我的正常工作流程正在根據API調用和DB 0的元信息對DB 1進行更新。我希望盡一切努力Lua腳本,但無法弄清楚如何擊中多個dbs。我使用redis-py在Python中執行此操作:使用多個數據庫和一個Redis Lua腳本?

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

由於客戶端意味着特定的數據庫,因此我被卡住了。想法?

回答

5

將相關數據放入不同的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腳本都必須重置當前數據庫,因此它會使複雜腳本變得繁瑣笨拙。

相關問題