我想使用redis缓存数据库查询。现在,单个API端点中的伪代码如下所示:
GET /data
我正在缓存不经常更改的objets,所以我将expiration设置为24h。问题是我想要更新这样的对象。伪代码如下所示:
PUT /data
问题是,在将新数据写入缓存(或缓存已被删除)后,仍然GET /data
可以用旧数据覆盖缓存中的新数据。如果在GET /data
的第2点之后执行第4点表单PUT /data
,就会发生这种情况。
是否有任何机制可以防止用缓存中的旧数据覆盖新数据?
答案 0 :(得分:3)
如果PUT
将新数据放入缓存中,并将其放入数据库(直写缓存),则可以使用SET
/ {{1在从HSET
写入缓存时,从PUT
和SETNX
/ HSETNX
写入缓存时。由于GET
仅在密钥不存在时才会写入缓存,因此通常GET
会成功。但是如果其他人(可能是SETNX
)出现并在此期间设置了密钥,则PUT
将失败,因为该密钥已经存在,并且您将获得所需的结果。< / p>
如果SETNX
只是删除了要由下一个PUT
重新填充的缓存中的数据,我认为您无法提供比现有更好的保证。从数据库中检索数据后,数据将存在一个到期时间,这并非严格错误,只是比您想要的更糟糕。
答案 1 :(得分:3)
@hobbs建议的NX方法仍有竞争条件。我将使用围绕您的GET工作流的WATCH / MULTI / EXEC块添加它,以实现类似事务的行为。
使用仅限NX的方法,仍然有可能在3到4之间,PUT会阻碍。