获取或设置Python中Redis中多个键的缓存

huangapple go评论70阅读模式
英文:

Get or set cache for multiple keys in Redis with Python

问题

Here's the translated code part you requested:

我正在尝试获取和设置多个缓存键但如果尚未设置键则需要更新缓存这是我当前的代码

import os
from redis.client import Redis

REDIS_HOST = os.environ["REDIS_HOST"]
REDIS_PORT = int(os.environ.get("REDIS_PORT", 6379))

redis_client = Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)

DEFAULT_CACHE_TIMEOUT = int(os.environ.get("DEFAULT_CACHE_TIMEOUT", 60 * 60 * 24))


def get_or_set_cache(key, default, timeout=DEFAULT_CACHE_TIMEOUT, function_args=None, function_kwargs=None):
    # type: (str, any, int, *any, **any) -> any
    """Get value from cache or set default value to cache and return it"""
    cached_result = redis_client.get(key)
    if cached_result:
        return cached_result

    if type(default).__name__ == 'function':
        result = default(*function_args or (), **function_kwargs or {})
        redis_client.set(key, result, timeout)
        return result
    else:
        redis_client.set(key, default, timeout)
        return default

If you need further assistance or have any questions, please feel free to ask.

英文:

I'm trying to get and set multiple cache keys, but I need to update the cache if the key is not set yet, this is what I currently have:

import os
from redis.client import Redis

REDIS_HOST = os.environ["REDIS_HOST"]
REDIS_PORT = int(os.environ.get("REDIS_PORT", 6379))

redis_client = Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)

DEFAULT_CACHE_TIMEOUT = int(os.environ.get("DEFAULT_CACHE_TIMEOUT", 60 * 60 * 24))


def get_or_set_cache(key, default, timeout=DEFAULT_CACHE_TIMEOUT, function_args=None, function_kwargs=None):
    # type: (str, any, int, *any, **any) -> any
    """Get value from cache or set default value to cache and return it"""
    cached_result = redis_client.get(key)
    if cached_result:
        return cached_result

    if type(default).__name__ == 'function':
        result = default(*function_args or (), **function_kwargs or {})
        redis_client.set(key, result, timeout)
        return result
    else:
        redis_client.set(key, default, timeout)
        return default

The problem with this is it is one key + value at the time, I would like to improve this by using similar logic to get/set multiple keys at the same time (1 connection to Redis), is there a way to do it?

This is what I tried:

https://stackoverflow.com/questions/3329408/is-there-mget-analog-for-redis-hashes

https://stackoverflow.com/questions/4929202/most-efficient-way-to-get-several-hashes-in-redis

https://stackoverflow.com/questions/42278433/python-redis-how-do-i-set-multiple-key-value-pairs-at-once

So it is possible to set or get multiple keys/values at the same time, but the missing logic is settting the cache if the key doesn't exists.

答案1

得分: 2

以下是已翻译的内容:

你可能正在寻找的是可以与 SET 命令一起使用的 NX 参数,以实现“如果键不存在则设置值”的操作。

举个例子:

> SET NAME ANKIT NX
OK
> SET NAME SAHAY NX
(nil)
> GET NAME
"ANKIT"

正如你所看到的,在第一条命令中,我除了使用 SET 命令外,还传递了 NX,这告诉 Redis 仅当 NAME 不存在时才将其设置为 ANKIT。在这种情况下,因为没有这样的键,所以会创建一个名为 NAME 值为 ANKIT 的键。

接下来,当我对同一个键 NAME 使用带有 NX 参数的 SET 命令时,它不会更改该键,因为它已经存在。

同样的操作也可以用于多个键,如下所示:

> MSETNX key1 value1 key2 value2 key3 value3
(integer) 1

唯一的限制是,如果其中一个键存在,MSETNX 将不会设置任何键。例如,看下面的示例:

> MSETNX key1 valuex key4 value4 key4 value5
(integer) 0

上述命令不会创建 key4key5,只因为其中一个多个键 key1 已经存在。

英文:

What you might be looking for is the NX argument that you can use with SET command to implement "set the value, if the key does not exist".

As an example:

> SET NAME ANKIT NX
OK
> SET NAME SAHAY NX
(nil)
> GET NAME
"ANKIT"

As you can see, in the first command, along with SET I also pass NX which tells Redis to set NAME as ANKIT only when NAME does not exist already. In this case, since there is no such key, a key with NAME and value as ANKIT is created.

Next when I run the SET command on the same key NAME with NX argument, it does not change the key, becuase it already exists.

The same can be done for multiple keys using MSETNX as shown below:

> MSETNX key1 value1 key2 value2 key3 value3
(integer) 1

The only catch is, MSETNX will not set any keys if even one of them exists. For example, see the following:

> MSETNX key1 valuex key4 value4 key4 value5
(integer) 0

The above command will not create key4 and key5, just becuase one of the multiple keys key1 already exists.

答案2

得分: 0

使用Redis管道功能。**pipeline = redis_client.pipeline()**您可以使用pipeline.get(key)获取键,然后根据您的用例进行实现。根据管道类型设计您的逻辑,即它是否是字典、列表或任何其他结构。一旦您知道了这一点,创建逻辑就变得容易。您可以看到pipeline是字典,因此将其打印到标准输出并可视化查看数据,然后您就知道还需要做什么。希望这有所帮助。

英文:

Yes use redis pipeline feature. pipeline = redis_client.pipeline()
You can get the keys as pipeline.get(key) and then implement as per your use case. Design your logic base don what pipeline type is i.e. is it a dict or list or any other structure. Once you know that then creating logic is easy part. You see pipeline is dict so print it on stdout and visually see the data and then you know what else to do. Hope this helps.

huangapple
  • 本文由 发表于 2023年5月7日 04:51:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定