如何在高流量和多个应用程序下更新分布式缓存?

时间:2016-05-31 09:59:30

标签: caching redis race-condition distributed-caching

我有N个服务使用M redis作为远程分布式缓存。假设现在多个服务想要检索相同的密钥,并且以下伪代码是工作的完成方式:

redisClient = getRedisClientByConsistentHash(key)
value = redisClient.get(key)
if value not exist
    value = getValueFromSomewhereElse(key) // line4
    redisClient set key value ex 1 nx // line5
return value

所以问题是:

在“line4”中,如果2个应用程序检索到不同的值,一个是较新的而另一个是旧的(应该被弃用),存储旧值的调用可能会在存储新值的调用之前发生,因此新值不会存储在redis中。如果我们引入一些分布式锁机制,问题仍然存在。

1 个答案:

答案 0 :(得分:0)

如果密钥存储在内部使用密钥的时间戳,使得如果需要将KeyA从ValueA更新为ValueB,则只有在大于上次更新时间戳的时间插入ValueB时才可以进行此更新。 KeyA。然后它保证只在特定密钥存储中插入新值。 OldValues无法覆盖NewValues(基于时间戳的协议)。 (不要知道redis是否遵循基于时间戳的协议)。

您的两个应用程序(例如A,B)都尝试从各自的主要redisClient获取密钥,但未找到密钥,因此他们从SomewhereElse获取密钥并找到关键,但A有旧,B有新。在这种情况下,几乎没有问题:

1. What if A's or B's primary `redisClient` itself gave you a value which is old?
2. How you come to know the value which is fetched is old or new?

解决方案:

1. Use a value which has majority (i.e the value received from atleast [ceil(M+1)/2] redisClients). Ofcourse this involves querying atleast [ceil(M+1)/2] rediClients which seems expensive.  (Paxos Theorem)
2. Depending upon application logic, most of the time you don't require latest values. That is, if the application requirement is to just check the presence of a value then it does not matter whether the value is old or new.