课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
随着互联网的不断发展,越来越多的人都在学习软件编程开发技术,而今天我们就通过案例分析来了解一下,分布式锁的常见类型都有哪些。
互斥(MutualExclusion),这是锁基本的功能,同一时刻只能有一个客户端持有锁;
避免死锁(Deadlockfree),如果某个客户端获得锁之后花了太长时间处理,或者客户端发生了故障,锁无法释放会导致整个处理流程无法进行下去,所以要避免死锁。常见的是通过设置一个TTL(TimeToLive,存活时间)来避免死锁。假设设置TTL为3秒,如果3秒过后锁还没有被释放,系统也会自动释放该锁(TTL的设置要非常小心!这个时长取决于你的业务逻辑)。可是这也存在一个问题,假如进程1获取了锁,然后由于某些原因(下面会说到)没有来得及更新TTL;3秒后进程2来获取锁,由于TTL已过,进程2可以获得锁并开始处理,此时同时有两个客户端持有锁,可能会产生意外行为。所以我们不能只有TTL,还需要给锁附加一个ID(或fencingtoken)来标识锁。上述逻辑中,当进程1获取到锁后记为LOCK_1;TTL过后进程2获取到的锁记为LOCK_2。之后,我们可以在应用层面或锁服务层面检查该id,来阻断旧的请求。
容错(Faulttolerance),为避免单点故障,锁服务需要具有一定容错性。大体有两种容错方式,一种是锁服务本身是一个集群,能够自动故障切换(ZooKeeper、etcd);另一种是客户端向多个独立的锁服务发起请求,其中某个锁服务故障时仍然可以从其他锁服务读取到锁信息(Redlock),代价是一个客户端要获取多把锁,并且要求每台机器的时钟都是一样的,否则TTL会不一致,可能有的机器会提前释放锁,有的机器会太晚释放锁,导致出现问题。
值得注意的是,容错会以性能为代价,容错性取决于你的系统级别,如果你的系统可以承担分布式锁存在误差,那么单节点或者简单的主从复制也许就能满足;如果你的系统非常严格,例如金融系统或航天系统,那么就要考虑每个cornercase——本文更倾向于讨论后者。
我们会拿着这三个属性逐一分析各种分布式锁的实现。在此之前,先把分布式锁分为两大类:自旋类和监听类。
自旋类包括基于数据库的实现和基于Redis的实现,这类实现需要客户端不停反复请求锁服务查看是否能够获取到锁;
监听类主要包括基于ZooKeeper或etcd实现的分布式锁,这类实现客户端只需监听(watch)某个key,当锁可用时锁服务会通知客户端,无需客户端不停请求锁服务。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。