深入浅出分布式技术原理
陈现麟
伴鱼技术中台负责人,前小米工程师
21241 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 39 讲
深入浅出分布式技术原理
15
15
1.0x
00:00/00:00
登录|注册

07|分布式锁:所有的分布式锁都是错误的?

非阻塞接口 tryLock
阻塞接口 Lock
性能与正确性的权衡
高可用性
业务场景决定性能需求
底层服务组件的重要性
SLA要求
互斥语义的正确性
部分失败和异步网络问题
公平性
可重入性
完备的锁接口
超时机制
互斥
跨进程、跨机器的分布式锁
同一台机器上的多进程锁
进程内部的锁
单实例执行需求
定时任务
临界区资源:分布式系统共享资源
控制对象:多个进程
保证临界区代码的一致性
并发控制工具
存储系统选择的原则
分布式锁服务的设计目标
实现分布式锁服务的关键特性
分布式锁服务的必要性
高可用和高性能的权衡
正确性问题
分布式锁的特性
锁的层次
分布式锁场景
分布式系统中的锁
锁的定义
思考题
总结
分布式锁的挑战
怎么实现分布式锁
为什么需要分布式锁
分布式锁的相关问题

该思维导图由 AI 生成,仅供参考

你好,我是陈现麟。
通过学习“配置中心”的内容,你已经理解了在分布式系统中,为什么需要配置中心,以及怎么去实现一个设计良好的配置中心,现在,你终于不用再为管理极客时间后端各种服务的配置而烦恼了,这是一件值得高兴的事情。
但是,在极客时间后端系统快速迭代的过程中,你发现了一个服务中的代码逻辑问题:在有些场景下,你并不想让所有的实例都一起运行,只需要一个实例运行就够了,比如在用户生日当天,给用户发的祝福短信等类似定时通知的情况。
目前同一个服务的所有实例都是对等的,只能每一个实例都运行。如果将这个服务运行的实例修改为一个,虽然能解决刚才讨论的问题,但是这个实例就变成了一个单点,会面临性能瓶颈和单点故障的风险。
这真是一个两难的问题,我们应该如何解决呢?其实,这个问题的本质在于,我们希望同一个服务的多个实例,按照一定的逻辑来进行协同,比如刚才讨论的定时任务的逻辑。那么多个实例在同一时刻只能有一个实例运行,它就是一个典型的分布式锁的场景
所以,在本节课中,我们将从“为什么需要分布式锁”,“怎么实现分布式锁”和“分布式锁的挑战”这三个层次依次递进,和你一起来讨论分布式锁相关的内容,解决你的困惑。

为什么需要分布式锁

确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

分布式锁在分布式系统中扮演着重要角色,本文深入探讨了分布式锁的必要性、实现方式以及面临的挑战。首先,文章介绍了分布式锁的基本定义和应用,强调了其在解决分布式系统中多进程临界区问题方面的重要性。其次,详细讨论了分布式锁的实现原理,包括互斥、超时机制、完备的锁接口、可重入性和公平性等特性。最后,指出了分布式锁在正确性、高可用和高性能方面面临的挑战,并提供了在实际工作中实现合适的分布式锁的指导。总体而言,本文为读者提供了快速了解分布式锁的基本原理和实现方式,为解决分布式系统中的并发控制问题提供了有益的参考。文章深入浅出,逻辑清晰,对分布式锁的重要性、实现方式和挑战进行了全面而深入的探讨,对于需要了解分布式锁的读者具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入浅出分布式技术原理》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • 啊树
    建议老师结合目前主流组件介绍哪些组件如何运用这些知识点,不然有点懵,不知道能干嘛

    作者回复: 我觉得学习技术可以分两个维度: 
1、一个原理论上或者广度上的,通过了解技术的业务场景、解决问题的原理和方案,以及这个技术需要注意和思辨的地方来掌握这个技术,这样在我们碰到这个业务场景是,能立即明白这是什么问题,应该怎么解决,难度和注意点是什么。一般来说,一些技术上不正确的决策,都是由于这些知识盲区导致的。 2、另一个是实践上或者深度上的,在业务上确定需要这个技术的时候,依据之前的理论知识,对开源项目进行选型或者选择自研都可以。这一部分可以在有需要的时候再做,现在可以先快速拓宽知识的边界。 一般理论上的知识会比较稳定,不容易过时,而具体项目的实现,首先项目本身会迭代而改变,另外后面也会有其他新的项目出来,是会快速改变的。所以这个专栏主要是对技术原理上的讨论,这个部分是需要对这个方向有一定经验的人来总结的,如果你对某一个知识点非常感兴趣,那么在学习好技术原理后,可以对你感兴趣的一个或几个项目来做具体的分析,一定会受益匪浅。

    2022-02-13
    29
  • 刘章
    高可用我会选zookeeper,要求不高,选Redis

    作者回复: 👍👍

    2022-03-06
    5
  • 处女座♍️
    结合业务实践,项目初步阶段用redis作为分布式锁,业务量上来后考虑安全可用会改成zk,不过目前redis能满足80%业务。。

    作者回复: 几乎不是要求非常高正确性的场景,都可以用Redis,不过业务量上来后,换成zk要好好评估,zk的性能比Redis要差了一个数量级。 比较好的方式还是以性能和正确性来选择分布式锁,课程中有讨论。

    2022-03-17
    3
  • 葡萄糖sugar
    “但是因为响应超时,客户端以为自己没有获取锁的情况发生。这样一来,依然会在一定程度上,影响锁的互斥语义的正确性”。老师,这段我不是很理解,为什么会影响到锁的互斥?客户端以为自己没有获得过锁,然后另一个竞争锁的客户端会尝试获得锁,此时并不会出现同时拥有同一个锁的问题,那为什么还会影响锁的互斥呢?

    作者回复: 这里的意思是指互斥语义是一定能保证同一时刻有一个客户端能获取锁的,但是现在的情况是所有的客户端都不能获取到锁。

    2022-02-11
    3
  • 约书亚
    当初看martin kleppmann与antirez的争论,学到了不少东西

    作者回复: 👍

    2022-04-13
    2
  • HappyHasson
    请教老师: “在单机情况下,我们可以非常方便地通过操作系统提供的机制,来正确判断一个进程是否存活,比如,父进程在获得进程挂掉的信号后,可以去查看当前挂掉的进程是否持有锁,如果持有就进行释放” ----老师能否举个例子,我没在实际项目中见到过这种实现。父进程需要知道子进程的具体逻辑才能帮忙释放锁吧?

    作者回复: 可以在加锁成功的时候,写入当前获得锁的进程ID,这样父进程在子进程崩溃的时候,去检查一下当前锁是否为挂掉的子进程持有的,如果是的,就释放锁。

    2022-02-16
    2
  • 陈阳
    老师 对于这些问题,如果我们获得锁是为了写一个共享存储,那么有一种方案可以解决上面的问题,那就是在获得锁的时候,锁服务生成一个全局递增的版本号,在写数据的时候,需要带上版本号。共享存储在写入数据的时候,会检查版本号,如果版本号回退了,就说明当前锁的互斥语义出现了问题,那么就拒绝当前请求的写入,如果版本号相同或者增加了,就写入数据和当前操作的版本号。 什么情况下会出现版本号回退?

    作者回复: 比如 a 操作或者锁了,并且版本号为 1,但是由于 GC 等原因,操作被挂起了。在 a 操作挂起的时候,锁过期了,b操作又获得了锁,版本号为 2,并且写入成功。这个时候,a 操作已经恢复了,再进行写入操作的时候,就会出现版本回退的问题。

    2022-02-15
    2
  • shuff1e
    请教老师: 所以,我认为对于在共享存储中写入数据等等,完全不能容忍分布式锁互斥语义失败的情况,不应该借助分布式锁从外部来实现,而是应该在共享存储内部来解决。 在共享存储内部解决什么问题?和文章中所说的fencing token有什么关系?

    作者回复: 我们往共享存储中写入数据的正确性: 一种是从外部通过 fencing token 来保证,其实是一种抽象泄漏。 另一种是由共享存储自身来保证,所有的分布式数据库都是这样做的,这样的抽象对使用者更友好。

    2022-02-13
    2
  • GaryYu
    什么情况会发生 响应超时客户端以为没获取锁 但锁服务已经颁发锁 若响应超时客户端不会返回error给锁服务让这次获取锁失败吗?

    作者回复: 比如 锁服务 的逻辑颁发锁成功,但是通过网络到客户端的时候发生丢包,还没有重试的时候,客户端已经超时了,或者是客户端已经收到锁,但是响应发送到锁服务的时候超时了。 对于锁服务来说,它不能区分超时是发生在客户端收到锁之前还是锁之后。

    2022-04-10
    1
  • 青鸟飞鱼
    老师,如果etcd作为分布式锁,我能想到的是网络分区时,少数节点会有问题。还有其他方面的问题吗?

    作者回复: etcd做分布式锁,在存储上的选择是没有问题,已经是一致性最好的存储了。 文章讨论的是分布式锁的正确性问题:一般在这种情况下,锁服务在进程加锁成功后,会设置一个超时时间,如果进程持有锁超时后,将锁再颁发给其他的进程,就会导致一把锁被两个进程持有的情况出现,使锁的互斥语义被破坏。

    2022-02-21
    1
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部