Как установить срок действия ключа хеша в Redis в зависимости от наличия ключа - PullRequest
0 голосов
/ 27 июня 2018

Я хотел бы установить срок действия некоторых хеш-ключей, и если это первый раз, когда hset ключ, я хочу установить срок действия, в противном случае, я предпочитаю сохранить срок действия, который установлен в первый раз .

Поскольку существует огромное количество хеш-ключей, я предпочитаю делать это в конвейере, однако нижеприведенная функция работает не очень хорошо.

Строка pipe.exists(hkey) возвращает obj для pipe, который всегда равен True, поэтому предложение if всегда идет в одну часть независимо от наличия хеш-ключа.

И мой вопрос: есть ли способ установить срок действия ключа хеша в соответствии с существованием ключа хеша с конвейером?

def test1(hkey, v):
    with r.pipeline() as pipe:
        # tmp = pipe.exists(hkey)
        # pipe.exists(hkey) is a pipe obj, which is always True, 
        # this line not work as expected and the two lines below it will never be excuted.
        if not pipe.exists(hkey):
            pipe.hset(hkey, v, v)
            pipe.expire(hkey, 3600)
        else:
            # no matter whether the hash key is exist or not, the if else statment always goes to this line.
            pipe.hset(hkey, v, v)
        pipe.execute()

1 Ответ

0 голосов
/ 27 июня 2018

Вы НЕ МОЖЕТЕ достичь этого с конвейером, поскольку вы никогда не узнаете, существует ли ключ, пока не будет выполнен весь конвейер. Вместо этого вы можете использовать Lua scripting для выполнения работы:

local key = KEYS[1]
local field = ARGV[1]
local value = ARGV[2]
local ttl = ARGV[3]

local exist = redis.call('exists', key)

redis.call('hset', key, field, value)

if exist == 0 then
    redis.call('expire', key, ttl)
end

Проверьте это , чтобы увидеть, как запустить скрипт Lua с помощью redis-py. Затем запустите сценарий с конвейером, чтобы уменьшить RTT.

UPDATE

Если вы настаиваете на использовании WATCH для выполнения работы, вы можете попробовать следующий код:

with r.pipeline() as pipe:
    while 1:
        try:
            pipe.watch(hkey)

            exist = pipe.exists(hkey)

            pipe.multi()

            if not exist:
                pipe.hset(hkey, v, v)
                pipe.expire(hkey, 3600)
            else:
                pipe.hset(hkey, v, v)

            pipe.execute()
            break;
        except WatchError:
            continue
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...