2

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

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

那么,实现键级锁的最佳方式是什么?Redis 是否支持开箱即用?ServiceStack 的IRedisClient.AcquireLock是否非常适合这种情况,或者如果我们不处理分布式锁,它是否有点矫枉过正?或者我最好自己实现锁,就像这里描述的那样?

提前致谢!

4

3 回答 3

2

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

  1. LPUSH创建互斥锁
  2. BRPOP锁定(这是阻塞)
  3. LPUSH解锁
于 2013-11-24T23:26:01.263 回答
2

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

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

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

于 2013-01-18T02:44:55.847 回答
0

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

于 2013-01-17T21:04:18.290 回答