📣 Back to School开学季 - VIP通行证5折优惠!蓝莓、Offer多多同步优惠
查看: 7212| 回复: 16
跳转到指定楼层
上一主题 下一主题
收起左侧

[经验总结] 系统设计之分布式锁(进阶必会)

 
全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
系统设计中,分布式系统和分布式知识考察是挺多的。其中,比较难的一块是分布式锁。

所以,这里我们一起来探讨下分布式锁的面试问题一般都考察哪些点,并且都用哪些方案来实现。

题目:请说明下什么是分布式锁,分布式锁的常见用途,最后,试着讨论下怎么实现一个分布式锁。

前面两个题的答案就放在帖子里面,大家可以自己先想想。

这里我们先展开讲讲实现。常见的,分布式锁有三种实现方式。
第一种,使用有ACID的SQL database。利用SQL database的ACID 保证,来锁住需要锁的field。
这种方案的优点是简单的。但是也有很多缺点。这里,缺点是什么呢?我们可以再回帖里面展开讨论。

第二种,是利用Redis。Redis性能更好, QPS更高。那么我能用Redis集群吗,还是只能用单机?如果是单机,该怎么做?会遇到哪些问题。如果是集群,会遇到哪些问题。

第三种,是用一些现成的consensus protocol和implementation,然后实现锁。比如zookeeper,chubby等。这个也比较长,我们在回帖展开。

现在先把问题大概放出来,然后我再慢慢给出答案。欢迎大家尝试作答,然后互相学习。谢谢!

如果大家感兴趣,还有一些我最近研究的分布式系统设计题目可以分享出来,比如payment,比如distributed transaction,distributed job scheduler等。

评分

参与人数 5大米 +20 收起 理由
Lulalala123 + 1 谢谢分享!
匿名用户4cfc935 + 2 很有用的信息!
葡萄的奶茶 + 10 欢迎分享你知道的情况,会给更多积分奖励!
whdawn + 6 给你点个赞!
tutuabm + 1 给你点个赞!

查看全部评分


上一篇:典型系统设计题目分析和进阶
下一篇:system design是不是alex xu的书最好?
全局:
用ACID db的问题
1. 没有TTL,客户端要自己心跳判断超时/续锁
2. 一般的db都没有类似于 if x = y then xx else yy这样的内置函数,需要自己写store procedure保证检查和获得锁在同一个事务 要不然就要用数据库的唯一约束 或者是内置的行锁比如 for update
3. 毕竟单机,分布式要解决的问题他都有
redis
1. 单机集群都可以,集群做个qurom写就行了,可以直接使用中间件比如redlock
2. 总之单机还是事务问题。想个办法把setnx和expire包在一起
zk/etcd
1. 吞吐量的问题,毕竟scalability没那么好
2. 好处是有类似于watcher的东西,毕竟设计就是个锁
3. 选举的时候可能不可用
4. 单主跨dc部署总有些潜在性能影响
回复

使用道具 举报

推荐
 楼主| 13-carotene 2023-1-19 11:32:44 | 只看该作者
全局:
前面很多答案都很优秀了。我再写个我的理解,同时增加下细节。
1. 用SQL的话就直接利用ACID特性。但是如果是单机SQL,就有SPOF问题。如果是分布式的SQL的话,就没有这个问题,但一般效率就比较差。如果你对SQL ACID很熟练,你也可以展开讲讲你的理解。实际上,要做好细节也非常多。

2. 用Redis的话,在新API加持下,可以直接set expiry,利用这个API加锁。Redis的QPS会比SQL高出很多(高多少,得会)。如果是用cluster Redis的话,那就会遇到分布式锁常见的一致性问题。Redlock是Redis分布式锁的一种实现。大概思想就是有N台机子,然后用拿到一半以上的锁就可以。当拿锁出现问题的时候,也要会处理。这里,大家可以自己搜下Redlock大概怎么work的。考官可能会问你可能情况下,怎么处理比较对。

(有人提到了这个Redlock是不是安全的这个对喷,有兴趣的可以去钻研下: https://martin.kleppmann.com/201 ... ibuted-locking.htmlhttp://antirez.com/news/101

3. 第三种就是利用zookeeper,chubby之类的。核心思想就是利用consensus。地里有个非常好的文章讲解这部分,我最不赘述了: https://www.1point3acres.com/bbs/thread-499338-1-1.html
回复

使用道具 举报

全局:
本质还是hig availability 和 strong consistency 的trade off.  取决于你的应用场景对一致性的要求。

第一种使用DB 类似 redis(单线程), 实现简单, 但是性能不好,有single point of failure. 如果使用数据库集群,则依赖数据库的一致性。

第二种使用redis 集群 + 普通读写锁,  性能好,高可用性, 遇到network partition 会发生脑裂问题,但非强一致性(比如client1 从 master拿到锁, 但是接着master 挂掉,新的master 没有备份锁信息,client2 从新的master 拿到第二把锁)。 另外不建议使用redlock,具体看Martin 的文章https://martin.kleppmann.com/201 ... ibuted-locking.html

Redlock 个人理解本质还是zookeper类似的quraom 实现强一致性, 而且redlock 严重依赖系统时钟,但是网络延迟,clock drift, GC pause 都会造成 同一个时间有可能 多个client 拿到锁。大多数情况大家都是因为性能好才选择Redis,对数据丢失或者不准确可以容忍,没必要为了强一致性 选择redlock 凭空增加复杂度 降低性能。目前Redlock没有得到大规模验证使用。

第三种 consensus protocol
比如zookeeper + fencing token 可以实现强一致性, 代价是写性能不高 而且选举的时候可能不可用.
Kubernetes 基于etcd 的lease  https://kubernetes.io/docs/concepts/architecture/leases/

评分

参与人数 1大米 +1 收起 理由
13-carotene + 1 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
sevenwonder 2023-1-18 04:19:35 | 只看该作者
全局:
wait for answers
回复

使用道具 举报

🔗
zhangming870 2023-1-18 05:12:21 | 只看该作者
全局:
wait for answers
回复

使用道具 举报

🔗
flyPacific111 2023-1-18 05:41:03 | 只看该作者
全局:
follow updates for this thread
回复

使用道具 举报

🔗
Dave2022 2023-1-18 09:47:38 | 只看该作者
全局:
DB:
UPDATE locks SET locked = 1 WHERE locked =0 and lock_id = {lock_id};
客户端检查被更新的行数==1即获得了锁。
缺点:客户端需要spin。
回复

使用道具 举报

全局:
Wait for answers
回复

使用道具 举报

🔗
蝎子莱莱_ 2023-1-18 12:52:12 | 只看该作者
全局:
Wait for big gods
回复

使用道具 举报

🔗
微风簇浪 2023-1-18 14:33:30 | 只看该作者
全局:
1. 用ACID db
应该还是single point of failure 因为是单机, 不是单机的话acid就是 分布式事务 和 分布式锁好像区别不大。

如何释放锁? 如果拿了锁之后, worker 挂了怎么办,

检查上一次拿锁的时间 变相实现ttl
2.
redis 应该是用单机吧。但是in memory DB  怎么实现 durability? 如果是redis 集群 quorum 的话 感觉很复杂。
3.

分布式锁 应该是 用leasae 和  心跳检查的方法 来避免worker 误以为自己拿到了锁的情况。
回复

使用道具 举报

🔗
cltgso 2023-1-18 14:52:15 | 只看该作者
全局:
zookeeper实现分布式锁,刚刚在另一篇文章里看到
简单来说
1.create ZNode with Sequence and ephemeral flag,创建一个zookeeper的节点.这里说的sequence和ephemeral是Zookeeper node的类型,sequence表示这类节点会带一个序列号,并且单调递增。ephemeral,暂时性节点,不知道中文对不对,就是只会存在session里,session没了它也没了
2.第一个zookeeper client 尝试call getChildren(),不使用watch 这个flag 注
3.step 2会拿到一个序列号(为zookeeper自动创建的递增序列),如果是当前client上最小,该client拿到锁
4.另一个client,call exists(),使用watch flag
5.如果step4 返回null,返回step 2,否则等待通知再进入step2

其中step2 的watch,就是一个zookeeper client去监视其他znode,第一个client不需要监视,因为它排在队伍第一位,后面的client需要监视,因为他们不知道前面有多少人在等
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表