当多个客户端同时尝试读/写项目时,Redis是原子的吗?

问题描述 投票:1回答:1

假设我有几个构成我的API的AWS Lambda函数。其中一个函数从单个Redis节点上的特定键读取特定值。业务逻辑如下:

if the key exists:
    serve the value of that key to the client
if the key does not exist:
    get the most recent item from dynamoDB
    insert that item as the value for that key, and set an expiration time
    delete that item from dynamoDB, so that it only gets read into memory once
    Serve the value of that key to the client

我们的想法是,每次客户提出请求时,他们都会获得所需的价值。如果密钥已过期,则lambda需要首先从数据库中获取该项并将其放回Redis。

但是,如果2个客户端同时对lambda进行API调用,会发生什么?两个lambda进程是否会读取没有密钥,两者都将从数据库中获取一个项目?

我的目标是实现一个队列,其中某个项目在内存中只存在X个时间,并且一旦该项目到期,下一个项目应该从数据库中提取,当它被拉出时,它也应该被删除这样就不会再拉了。

我试图看看是否有办法做到这一点,而没有一个单独的EC2过程,只是跟踪时间。

redis + lambda + dynamoDB是我正在努力完成的一个很好的设置,还是有更好的方法?

amazon-web-services redis aws-lambda amazon-dynamodb atomic
1个回答
2
投票

Redis服务器将以原子方式执行命令(或事务或脚本)。但涉及单独服务(例如Redis和DynamoDB)的一系列操作将不是原子的。

一种方法是通过在业务逻辑周围添加某种锁来使它们成为原子。例如,这可以是done with Redis

然而,这是一个代价高昂且相当麻烦的解决方案,因此如果可能的话,最好简单地将业务逻辑设计为在并发操作面前具有弹性。要做到这一点,您必须查看步骤并想象如果多个客户端同时运行会发生什么。

在您的情况下,我可以看到的缺陷是可以从DynamoDB读取和删除两个值,一个在Redis中写入另一个。使用Redis的SETNX(SET if Not eXists)命令可以避免这种情况。像这样的东西:

GET the key from Redis
If the value exists:
    Serve the value to the client
If the value does not exist:
    Get the most recent item from DynamoDB
    Insert that item into Redis with SETNX
        If the key already exists, go back to step 1
    Set an expiration time with EXPIRE
    Delete that item from DynamoDB
    Serve the value to the client
© www.soinside.com 2019 - 2024. All rights reserved.