2014-01-15 104 views
-1

我想通过使用使用ServiceStack.Redis c#连接redis。Lua脚本优化

我已经写下面的代码来验证基于指定密钥的数字。

argv[1]是关键

argv[2]是数

string strScript = " local intCurrentVal = redis.call('GET', '' .. ARGV[1] .. ''); \n" 
    + "if (tonumber(intCurrentVal) <= 0) then return 1 elseif ( (tonumber(intCurrentVal)) - (tonumber('' .. ARGV[2] .. '')) < 0) then return 0 end;" 
    + "local intUpdatedVal = redis.call('SET', '' .. ARGV[1] .. '',(intCurrentVal - tonumber('' .. ARGV[2] .. '')));" 
    + "local intCurr = redis.call('GET', '' .. ARGV[1] .. ''); return intCurr"; 

逻辑步骤:

  • 得到的电流值
  • 检查,如果电流值不应该是小于或等于0
  • 检查是否存在租值 - 传递值应不小于Ø
  • 如果当前值 - 传递不那么少0,则设置(当前值 - 传递)作为当前值
  • 获取当前值

是否有可能优化和调整以下lua脚本的性能。请帮忙。

+0

它必须在交易区块内。 – user2771292

+0

什么事务块? – Schollii

+0

关于我们每秒钟谈论多少次交易?你有没有分析过,发现Lua脚本是问题? – dualed

回答

1

原始格式是可怕的 - 所以往往是性能。

local key = tostring(ARGV[1]) 
local number = tonumber(ARGV[2]) 

local current = tonumber(redis.call('GET', key)) 

if current <= 0 then 
    return 1 
elseif current < number then 
    return 0 
end 

redis.call('SET', key, current - number) 
return redis.call('GET', key) 

进一步的优化步骤可以包括:全局函数本地化(像字符串,tonumber等),在LUA_REGISTRYINDEX表缓存编译块。

+0

我确实同意你的看法,但我想在一个事务处理块中包含相同的内容,这就是使用lua脚本的原因。 – user2771292

+0

最后2行我在INCRBY api调用redis时替换了它 – user2771292