英文:
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
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
上述命令不会创建 key4
和 key5
,只因为其中一个多个键 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论