阻止访问Redis密钥(ServiceStack)

时间:2013-01-17 20:45:57

标签: asp.net-mvc redis servicestack

我正在尝试使用ServiceStack Redis客户端实现我认为非常常见的缓存方案,但我很难找到一个很好的例子。

在ASP.NET MVC应用程序中,我们对外部Web服务进行相对长时间(和计量)的调用,并将结果缓存一段时间。在缓存实现中,希望在Web服务调用完成之前阻止对该密钥的其他请求,以避免额外的(昂贵的)调用。

那么,实现密钥级锁定的最佳方法是什么? Redis是否支持开箱即用? ServiceStack的IRedisClient.AcquireLock是否适合这种情况,或者如果我们不处理分布式锁定,它是否过度?或者我最好自己实现锁定,如描述here

提前致谢!

3 个答案:

答案 0 :(得分:2)

Redis是一个非阻塞的异步服务器,在密钥空闲之前,redis没有内置语义来阻止客户端连接。

注意:Redis是一个远程NoSQL数据存储,因此您实现的涉及redis的任何锁都是按设计“分布式”的。 ServiceStack的AcquireLock使用redis的原始 SETNX 锁定语义来确保只有1个客户端连接具有锁定,所有其他客户端/连接都保持阻塞,直到通过使用指数重试后退乘数进行轮询来释放锁定

为了在不轮询的情况下实现分布式锁定,您需要创建一个解决方案,该解决方案使用SETNX + redis的Pub / Sub支持组合来通知等待的客户端锁定已被释放。

答案 1 :(得分:2)

我使用以下模式将Redis用作全局网络互斥锁:

  1. LPUSH 创建互斥锁
  2. BRPOP 锁定(这是阻止)
  3. LPUSH 解锁

答案 2 :(得分:0)

为什么不在要锁定的密钥上发出SETNX?如果可以设置/锁定密钥,则返回1。并且如果它已经存在则为0,因此不能进行锁定。有关具体信息,请参阅http://www.redis.io/commands/setnx