8

我对 redis 非常陌生,并且仍在使用它。我想测试它是否与我的项目相关,但我不确定我正在运行的特定命令。SO 上的用户让我相信使用管道和事务的性能优势,所以我想我会问如何做到这一点。

基本上我有两个声明,我只想发布而不需要等待结果(似乎是管道衬里的一个很好的候选者。它看起来像这样:

Does valueX exist?
If it does insert valueY

它非常简单,但到目前为止,我一直在研究它的所有方法似乎都在等待 ValueX 是否存在的响应,并且因为我正在执行我的程序的十亿循环,所以它会停止运行。

这可能吗?如果它有帮助,我正在使用 Java,但还没有确定哪个客户端库(jedis 或 jredis,仍在测试)。实际上,我什至还没有完全确定 redis,但非常倾向于它(似乎对我正在做的速度很好),所以任何建议都是可以接受的。

4

2 回答 2

7

不,暂时不可能完成这样的事情。您需要的是目前缺少的功能,但它将在 2.6 版本的 Redis 中提供。这称为 LUA 脚本。您可以一并执行依赖于先前命令的服务器命令,而无需在客户端获取它们。有关更多详细信息,请参见此处

于 2012-03-08T07:49:48.093 回答
1

Redis 不直接支持这一点,但在许多情况下,这通常是需要的。更广义的“原子”模式是:

Check multiple conditions
If all satisfied, run multiple commands

这可以通过简单的 lua 脚本来实现

-- Validate conditions and exec commands if ok

local params = cjson.decode(ARGV[1])

-- Check conditions
for __, check in pairs(params["if"]) do
    if #check == 2 then
        if check[1] ~= redis.call(unpack(check[2])) then return 0 end
    elseif check[2] == "==" then
        if check[1] ~= redis.call(unpack(check[3])) then return 0 end
    elseif check[2] == "!=" then
        if check[1] == redis.call(unpack(check[3])) then return 0 end
    elseif check[2] == ">" then
        if check[1] <= redis.call(unpack(check[3])) then return 0 end
    elseif check[2] == "<" then
        if check[1] >= redis.call(unpack(check[3])) then return 0 end
    else
        error('invalid operator "'..tostring(check[2])..'" (expected "==", "!=", ">" or "<")')
    end
end

-- Eval redis commands
for __, exec in pairs(params["exec"]) do
    redis.call(unpack(exec))
end

return 1

然后可以简单地传递交易细节JSON.stringify(object)

{
  // Conditions. All must be satisfied
  if: [
    [ 'initialized', '==', [ 'sget', 'custom-state' ] ]
  ],
  // Commands to execute if all conditions are satisfied
  exec: [
    [ 'set', 'custom-state', 'finished' ],
    [ 'incr', 'custom-counter' ]
  ]
}

在许多情况下,此类“条件事务”消除了对自定义脚本的需求。

有关更多示例/测试/src,请参阅https://github.com/nodeca/redis-if

于 2021-02-19T17:58:28.287 回答