Azure是否有针对带有键的分布式锁的开箱即用解决方案?

7

我希望能够像这样编写代码:

using (await LockAsync(x.Id))
{
    // here goes code that is unsafe with respect to x.Id
    // because it can be executed in multiple threads on
    // the same instance or on multiple instances (e.g.
    // multiple Azure Functions
}

我知道有一些开箱即用的方法可以锁定整个执行上下文,而不需要使用密钥(例如函数中的[ActivityTrigger]),我也知道我可以使用blob租赁来自己创建密钥锁,但是是否有一种开箱即用的方法可以进行密钥锁定呢?


1
据我所知,目前没有办法在多个Azure函数应用程序之间建立内置的锁。 - Sebastian Achatz
Microsoft.Azure.WebJobs.Host 命名空间中的 CloudBlobContainerDistributedLockManager 可能是一个不错的选择。 - spongessuck
3个回答

2
在Azure存储中,使用"租赁Blob"功能可以实现这一点。Azure函数实际上使用此功能来协调函数的多个实例之间的操作。
如果我想在"x.Id"上获取锁定,则可以使用Azure存储,在路径"/my-app-locks/{x.Id}"下获取一个60秒的存储租约,该租约对应一个0字节的Blob。如果我获得了租约,则知道我拥有锁定;如果没有,则意味着其他人拥有锁定,并且我可以轮询它,直到他们释放它。在租约到期之前,您还可以续订60秒的租约以延长时间。
这篇博客提供了一些代码和详细信息,以及其他实现方式 - https://medium.com/@fbeltrao/distributed-locking-in-azure-functions-bc4517c0306c

2
你可以使用Redis分布式锁。 RedLock.net包提供了你所需要的功能。将原始答案翻译成“最初的回答”。
var resource = "the-thing-we-are-locking-on";
var expiry = TimeSpan.FromSeconds(30);


using (var redLock = await redlockFactory.CreateLockAsync(resource, expiry)) // there are also non async Create() methods
{
   // make sure we got the lock
   if (redLock.IsAcquired)
   {
    // do stuff
   }
}

阅读完https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html之后,你对Redis分布式锁的看法将会发生改变。如果你想要一个真正的分布式锁,Redis并不是答案。 - JengdiB
@JengdiB,感谢分享链接。你会建议使用哪种方法来作为真正的分布式锁呢? - R.Titov
@R.Titvov 我也是新手。但是,我会选择 Apache Zookeeper 来完成我的工作。它是一种持久连接式的分布式锁。如果您失去了与 Zookeeper 的连接,则会失去您的锁定,其他人可以获取它。 - JengdiB
@JengdiB,如果在锁定操作期间,其中一个实例与Zookeeper失去连接,另一个实例将获取锁定,然后第一个实例将恢复连接,会发生什么情况?根据您之前的评论,似乎在锁定中会有两个操作。如果我错了,请纠正我。 - R.Titov

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接