我们有使用Azure数据库的Web。数据库模型有客户和管理人员。客户可以添加约会。对于同一个经理,我们不能允许来自两个或更多客户的重叠约会。由于我们是在分布式环境中工作( web服务器的多个实例可以同时将记录插入数据库),因此有可能保存无效的约会。例如,客户1希望在10:00 - 10: 30之间预约。客户2要10点15到10点45之间的预约。如果两个约会同时进行,那么Web中的验证代码将不会捕获错误。这就是为什么我们需要像分布式锁管理器这样的东西。我们从Redis和动物园管理员那里读到了Redlock的故事。我的问题是:对于我们的用例,Redlock或Zookeeper是好的选择,还是有更好的解决方案?
如果我们使用Redlock而不是,因为我们已经使用Azure来承载我们的Web。我们计划使用ManagerId + Date来识别共享资源(我们希望锁定的资源)。这将导致Manager在某一天锁定,因此在其他日期为同一Manager设置其他锁是可能的。我们计划使用Azure Redis Cache的一个实例,这是否足够安全?
发布于 2018-11-21 21:12:22
Q1:对于我们的用例,雷德洛克或动物园管理员是很好的选择,还是有更好的解决方案?
我认为Redlock不是用例的最佳选择,因为:
a)它的保证是在使用DB操作之前设置的特定时间(TTL)。如果出于某种原因(向DevOps询问难以置信的原因并检查如何进行分布式锁定),则DB操作所需的时间要比TTL长,您需要解除锁有效性的保证(请参阅正式文件中的锁有效性时间)。您可以使用大型TTL (分钟),也可以尝试使用另一个线程来扩展其有效性,该线程将监视DB操作时间--但这变得非常复杂。另一方面,在动物园管理员( ZK ),您的锁在那里,直到您删除它或进程死亡;这可能是您的DB操作挂起的情况,这将导致锁也挂起,但是这些问题很容易被DevOps工具发现,这将杀死挂起的进程,这反过来将释放ZK锁(还有一个监视过程的选择,它也可以更快地完成这一任务,并且更适合您的业务方式)。
( b)当试图锁定进程时,必须“战斗”才能赢得锁;“战斗”假设它们等待,然后重试获得锁。这可能导致重试计数溢出,从而导致无法获得锁。在我看来,这是一个不太重要的问题,但ZK的解决方案要好得多:没有“战斗”,但所有进程都会排队等待获得锁(检查ZK锁方)。
( c) Redlock是基于时间度量的,这是令人难以置信的棘手之处;至少检查如何进行分布式锁定中包含“感觉沾沾自喜”的段落(结论段也是如此),然后再考虑一下这个TTL值应该有多大,以确保您基于RedLock (时间)的锁定。
出于这些原因,我认为RedLock是一个风险很大的解决方案,而则是一个很好的用例解决方案。其他更好的分布式锁定解决方案适合您的情况,我不知道,但其他分布式锁定解决方案确实存在,例如,只需检查Apache ZooKeeper与etcd3。
Q2:我们计划使用Azure的一个实例,这足够安全吗?
对于您的用例来说,它可能是安全的,因为TTL似乎是可预测的(如果我们真的相信时间测量--请参阅下面的警告),但是只有当主程序接管失败的主程序可能被延迟(如果可能的话,您不确定应该检查Redis配置功能)。如果在锁与从进程同步之前释放主锁,则另一个进程只能获得相同的锁。Redlock建议使用延迟重启(在正式文件中检查性能、崩溃恢复和fsync ),时间至少为1 TTL。如果由于Q1:a+c原因,您的TTL比您的系统更长,那么您的系统将无法在不可接受的大时间内锁定(因为您拥有的唯一一个Redis主服务器必须以延迟的方式被从属程序替换)。
PS:我再次强调读一下马丁·克莱普曼( Martin )的关于Redlock的意见,在这里你会发现数据库操作被延迟的难以置信的原因(在到达存储服务之前进行搜索),以及不按时间测量锁定时间的难以置信的理由(同时也是反对使用Redlock的有趣论证)。
https://stackoverflow.com/questions/36549656
复制相似问题