技术解析

用 redis 做分布式锁这种骚操作是怎么流行起来的?
0
1975-02-23 03:22:01
idczone
Redis 根本就不是设计出来干这个的,为什么网上这么多垃圾文章讲这个?

老老实实用 ZK 或者 ETCD 不好吗?

感觉大量的垃圾技术文章的内容都可以总结为三句

1 我没读文档瞎 jb 用,结果不符合国外服务器预期。
2 出 bug 了受不了才老老实实读文档,原来是我用的不对。
3 按照文章老老实实的写代码,终于对了。


看多了会觉得中文技术社区真是垃圾堆。
用楼主的例子,如果一个订单 1000 万美金的系统你会以分布式锁来作为最终的成交判定么?
所以 0.0001 的错误概率有什么问题?

建议查看一下楼主的美国博士是否是造假的。Redis 官方文档上就有。为什么不看 ?是因为看不懂英文吗 ?

会。因为确认交易的前提是有程序去接受请求,如果没有分布式锁,你的主从怎么决定呢?

文档写了就是对的吗?

问:老老实实用 ZK 或者 ETCD 不好吗?
答:部分公司的码农并不会玩分布式中间件,也缺少相关的运维经验,固 Redis 解决问题啦,多快好省。
非学术讨论,达到项目效果 Run 起来时对于部分开发而言逻辑就是这么简单、朴素。

看楼主言论,分布式锁用 MySQL 再适合不过了

那你为什么还来垃圾堆里呢? Block 了 阴阳怪气

既然楼主知道 lamport,也应该知道 raft 用了 lamport 推荐的 TLA 证明安全性,那楼主手动用 tla 证明 redis 方案不靠谱不就行了

其实我也一直纳闷为什么动不动就是拿 redis 做队列,动不动就是 redis 做分布式锁。还满是优越脸…那您 redis 崩了别来找我啊,云端 redis 运维够简单了吧,中断 30s 够快了吧。抱歉,就是有人要把 redis 当核心外部依赖…我昨天一看,所有服务都是这样,在 k8s 的环境下,如果 redis 挂了,全部雪崩…………

还有都贴官方推荐,所以用。那么问题来了,数据不一致的时候,哪怕一辈子就一次,偏偏几千万订单。你猜是你负责还是所谓的 redis 官方负责?
我一直对这种以内存为主的单机行为分布式锁抱有怀疑。内存天然不靠谱。连个分布式协议都没有…我没想明白为什么这么多人觉得这个玩意是绝对可靠的

分布式锁感觉可以用比特币的去中心化思想来实现一下?

tla+一般用来证明

tla+一般是作者自己去证明自己的模型的正确的,才能令人信服,而事实是,还没用上 tla+,人反对者都给出“不靠谱”的时序了



1000 万美金的系统还用 Redlock 那是自己作死。人家文档里都说了无法保证 C,不看文档能怪谁。上千万的系统没个设计文档没个安全审计,逗谁呢?都搞上千万的分布式系统了,还请不起一个专业搞分布式的来审计一下算法?技术负责人干什么用的?就是拍板负责用的啊。谁是老板谁负责。
什么情况下可以用?
1. 东西不值钱,不存在你说的 1000 万。
2. 活该傻逼不看文档
3. 不要求强一致,再维护一套 ZK 集群又太麻烦。比如楼上某些人提到的,第三方 API 限制频率。偶尔 miss 一次不是不能接受,但是不挡一下又不好。既然已经在用 Redis,那用个现成的 Redlock 实现也是顺理成章的事情。
说到底:不看文档就瞎用自己不懂的算法那就是活该。谁用谁负责。

有点……意思:D

要证明不安全只需要一个反例。
要证明安全则必须要靠推导。所以真的需要绝对正确的软件,那得先写出数学推导,然后把数学算法转换成代码,再证明数学模型和代码等价。这样做是可以保证没用 bug 的(只要硬件不出问题)。
当然,实际上需要这么干的软件非常非常少。大部分程序员就是写几个 test case,然后上线的时候灰度上线就算了。如果真的是这个行业的人,也不可能不看文档,只看一篇百度就瞎 JB 用。
你说的垃圾技术文章问题,和中文无关。英文的垃圾文章也多了去了。只不过作为中文 native speaker,既然都在看英文文章了,大部分还是会去看官方文档的人。Aka,英文是个门槛。
但是如果完全脱离中文,直接就搜英文,你有非常大的概率会搜到垃圾英文文章。
比如有人今天手上就有个 redis,就想要个锁,你猜 Google 第一条是啥?
这是中文的锅吗?这明明是不看文档的锅。

神仙打架, 先留个名
等我学明白也来加入 battle

我觉得 lz 的意思不是无脑 redis 锁,是中文环境下的文档搞得好像只有这个方案,etcd/zk 的分布式锁成了原罪一样。实现需求不是非黑即白。还是要考量业务因素。但我比较反对的是说大额交易才要考虑 cp 。这点我观点跟 lz 相同,和钱打交道只能是 cp 不能考虑 ap 。哪怕只有 1 毛钱的东西。

/吃瓜
好复杂,oracle 一把梭(锁 吧

我觉得楼主主要的问题就是因为楼主是搞数学的,而不是搞工程的。搞数学的人有个什么问题?搞数学的人,他们总是追求绝对准确,绝对一致,而不考虑要达成这个条件需要付出的成本。而做工程的人关注的是在误差范围内,在可接受的范围内,成本最低。Redis 做分布式锁确实无法保证一致性,但是在什么样的并发情况下才能暴露出这个问题?项目如果达不到这个量级为什么不行。楼主一来就提一个什么一千万的系统。系统都是从最小系统一层一层搭建起来的,一开始甚至连锁都没有,随着业务的增加而逐渐增加组件。业务规模在一定范围内,Redis 做分布式锁是最经济最有效最低成本的方式。等到业务规模继续扩张,再上 etcd 。楼主搞数学的这批人,就是一上来就想搞个可以用一万年的完美系统。一上来就 cap 分析来分析去,不考虑工期,不考虑成本,不考虑现阶段用不用的上。很多公司就是这样被拖死的。

楼主就是来秀优越的
先捶 Redis,再捶作者
然后假设会有 0.0001 的几率出问题,自己也不给出数据证明
后面再装 X 说一句“一个算法在没有数学证明之前,总是要假设它是错的。没有证明,不管多少人说是对的,也是不行的。”
你咋不给个你 0.0001 怎么证明来的呢?好话坏话全给你说了呗
说完就不假设 ZK 和 ETCD 的出错几率了,绕过直接谈设计初衷。寻思这俩在生产环境中在你看来是 100%不会出错咯?
真有你的。

放的同一个链接非常充分地证明了 OP 的观点…… 我不知道怎么有脸说 “官方的推荐用法怎么是骚操作?” 的?
哦原来是不懂英文的虫族,那我稍微作点人族的翻译工作。
> 因为一直有人拿 Redis 以各种各样的方式错误地实现分布式锁,所以我们还是弄个官方的分布式锁。
> 那我们官方摆个稍微复杂稍微有效的规范化的实现搁这儿了,你们来看看这个算法咋样?

实际上提出这些存在的问题是很有必要的,但我觉得 lz 有点戾气太重。首先不是所有场景都像楼主说的 1000 万美金的订单那么夸张。有很多系统 没那么庞大 也不是要求数据必须百分百正确 可以容忍一定的错误 但是 又想尽可能最大程度的正确 这时候加个 redis 的锁就很合适了 一是基本很少有系统不用 redis 现成的 redis 拿来就用 很方便 如果另外搞 zk/etcd 又得多维护一个组件 还得多搞几台机器 这都是成本 搞技术的不是人人老板啊 可以随心所欲随便加机器加组件 如果可以 谁不想搞个几百台机器来个超大系统 来提升自己呢?就像现在到处都是文章介绍 jwt 做登录 token 的。我一开始就觉得很鸡肋。因为我觉得 jwt 所谓的 serverless 就是鸡肋的东西。jwt 放出去,服务器控制不到。但是很多系统又有踢下线功能,多处登录只允许存在一个,以及很多场景下我可以随时终止这个 token 的生命。很明显,如果用 jwt 要做这种 必然需要另外搞一个值存储在服务端和 jwt 对应 才能终结 jwt 那这样所谓的 serverless 就没了意义。 那是不是 jwt 就没意义了?并不是。很多系统不一定就需要踢下线 需要服务端终结 jwt 的生命,亦或者给第三方服务做授权,亦或者做服务间的 token 也都行。技术是服务业务的,业务推动技术的发展。很多时候考虑技术选型不是看技术多么完美,而是要看技术和所要做的东西的契合度。抛开业务本身去讨论一个技术的完美度 这种情况可能只存在于学校了……

Google:distributed lock library
1. Distributed locks with Redis – Redis
2. madelson/DistributedLock: A .NET library for ... - GitHub
其中 Redis 部分就是 Redlock
3. Kleppmann's blog 之前提到的
4. Everything I know about distributed locks | by Davide Cerbo
推荐了 ShedLock, 和 ZK 、ETCD 没细看 ShedLock,但是看起来不是 Redlock 衍生物
5. Distributed lock manager - Wikipedia
Redis can be used to implement the Redlock Algorithm for distributed lock management.[10]
呵呵
6. The Top 7 Distributed Locks Open Source Projects
猜猜 Redlock 出现了几次
7. Distributed Locks are Dead; Long Live Distributed Locks
看起来是没啥问题。
8. Everything I Know About Distributed Locks - DZone Database
和 4 一样
9. Building Distributed Locks with the DynamoDB Lock Client
没有细看。看到 heartbeat every 10 seconds 就说明和 Redlock 是一个意思
10. distributed locking - npm search
猜猜这里面有几个 redis ?又有几个 Redlock ?
这就是 Google 第一页。你觉得这够不够垃圾?
垃圾文哪都有,英文社区也不比中文社区少。
至于多少钱需要考虑可靠性的问题,我就提几个:
1. 阿里抢月饼
2. 2010 flash crash,有一说是高频交易程序出 bug,或者 fat finger,然后触发做市商程序挂起。请问这种事情是多少概率?
3. Ariane 5,就问这个 bug 贵不贵?
事实就是,这个世界并不是这么的可靠。有相当多的人其实根本无法理解其重要性。同时也有相当多的人理解但选择忽视。当然咱不是故意去写 bug 。但是如果一共也就几万块钱的系统,管的是不那么重要的东西,你觉得老板会希望你多花一个月时间去实现一个可以提供形式验证的软件吗?你一个月工资也要几千了。
还有电商搞促销活动,抢占市场重要还是不被撸 bug 重要?大不了事后砍单就是了。甚至还有故意塞漏洞就是吸引你来撸的。
任何事情,都有其机会成本。实践中,重点不是绝对无 bug,而是在某些关键节点做好 damage control,同时完善日志,确保出了问题以后能够查到原因。很多时候,这就够了。

etcd 没有 redis 能扛得住高并发 我觉得

我觉得这篇文章可以看看: https://zhuanlan.zhihu.com/p/73807097

因为嘲讽像你这样的菜鸟很爽,连楼主说的是对是错都分不清,大概这就是“工程师红利”吧

太同意你的观点了,工程和科研是两码事,我带项目的时候是严禁那些理论派直接参与的,他们可以给出建议,但是 绝对不能让他们有太多的话语权。很多时候就是,他们说的都对,但是在现有的资源下不可能实现。


非常同意
我是材料工程和 CS 双学位。目前也是从事系统底层的工作,实践为主。说几个事情,恶心一下楼主:
1. 工程课教授:c 是一个经验常数,一般取 3
2. 工程课教授:这个公式的结果通常比实际稍大,但是没关系,我们下一步会取 10 倍安全余量
3. 工程课教授:这一大坨公式我们直接约等于 3
4. 老板:这个 corner case 你先别管,上线再说
5. 老板:这个 bug 我们都知道,但是很少见而且后果很小,先不修它
6. 老板:灰度上线跑了一个月了,有没有问题?没问题我们就放量了。
7. 我们之前都好好的啊,怎么到你这里就出 bug 了?
楼主呢,无非是想掉个书袋子,秀秀优越感。诚然,瞎 JB 用的傻逼是有,还不在少数。但是:
1. 如我楼上所说,垃圾文章到处都有,不局限于中文
2. 工程实现很多时候就是这么脏
3. 闻道有先后,术业有专攻
证明有 bug 很简单:举出一个 bug 就行。证明没有 bug 则是恶魔的证明。除非形式化论证,否则无法保证没有 bug 。
ZK 和 ETCD 是有设计模型的。虽然代码可能有 bug,但算法理论上是没问题的。
而 Redlock 的算法设计就是没有 C 的。

如果你需要的是高并发系统,那我非常怀疑你是否真的需要绝对的 C 。
同时我也很怀疑你是否真的应该用分布式锁实现这个目的。你去看实际生产中用的多的分布式的储存系统,以高性能为卖点的,其中有多少是强一致,又有多少用的是锁。不用锁,也有很多办法能保证程序的正确与高效,如何选择合适的分布式算法,这需要相关领域的知识。
该请人的时候就得请人。

实际上大部分工程上复杂的分布式系统会有条件的放弃 C,因为 A 和 P 太重要了。
放弃 C 也不是不一致了,而是从强一致模型改成比如最终一致或者增加补偿机制等。

没有最好的系统软件,只有最适合自己的系统软件。

小兄弟,这个世界并不是非黑即白的,不要走极端。所有的问题都应该放到合适的场景下去考虑,而不是像你这样一棒子直接全部打死。


ZooKeeper 和 etcd 的设计模型是说它自己的若干台机器之间要怎么通讯,但这里说的“分布式锁”是说 client 和 etcd/ZooKeeper/Redis 之间要怎么通讯,这是两码事。
这个事情早就有人讨论得很清楚了,给 “觉得中文技术社区真是垃圾堆” 的楼主贴一篇
http://zhangtielei.com/posts/blog-redlock-reasoning.html
http://zhangtielei.com/posts/blog-redlock-reasoning-part2.html

其中对 Martin Kleppmann 的观点有实质性反驳作用的其实是
ZooKeeper 也一样存在 Martin Kleppmann 说的问题



其实 AWS 提出了新的 PIE 理论,可能比 CAP 更加靠谱?


什么场景用什么东西,“一千万的订单出了问题谁负责”,处理钱的场景你用一个没有强一致的东西出了问题你说谁负责。

插个楼,看了看,我果然还是太菜了

工程当然是又脏又臭,充满 tradeoff 的 rabbish, 怎么能弄脏咱们高贵的数学家写公式的手?

是的啊 事实上服务业务时候是很多很恶心事情的。而且如楼主所说,即使各种技术文章分享 redis 的锁,那说明这个东西满足大部分人需求了,并且人家也只是分享他做过的案例,有他的场景和和限制在那里。作为观看者,如果不能分析出这个案例的利弊,那就是我们观看者的问题,而不是分享技术的那些人的问题,不能去怪别人为啥到处写 redis 锁而不写 etcd/zk 。这就很奇怪了。另外我觉得如果楼主单纯是想讨论 redis 锁对比 zk 和 etcd 的劣势,标题应该写 zk/etcd 为什么比 redis 锁好,或者 为什么 redis 锁不如 zk/etcd ? 这样才是一个合格的讨论某种技术的优劣问题 而不是上来就说 redis 锁是骚操作……

大佬们发布的关键词,,我一个都看不懂。。。

666

在业务角度,多数强一致性的东西,redis 分布式锁+mysql 唯一键都可以解决,我何必要额外加一套组件,多一些维护成本呢

看业务场景吧,一些简单的业务场景下,redis 不失为一个选择,而且 redis 实现起来真的很简单,如果说你的系统有 999999999 的可靠性要求,当我不存在

你们轻点锤,lz 简历都下架了

你可能没太明白我的意思,你举一个场景,一个订单 1000 万美金,在什么情况下会导致这个订单出错。
通过分布式锁来判定这个订单是否支付成功还是下单成功?

就当前环境来说,楼主说的是事实,实际上愿意去了解背后原因的人真的非常稀少,人们只想要现成的解决方案。既然 Redis 作为缓存组件几乎成了事实标准,那么再用它来实现分布式锁就显得顺理成章。只要官方说能用,那我们就用,官方说不行,我们就换。谁也说不准未来会不会又出现什么 xxdis 呢。赞赏楼主的态度,看到垃圾堆我们当然可以义愤填膺,也要顺手带走一两个易拉罐,免得它越堆越高。

工程的世界比较复杂,接触过国内某两个大厂的多套核心分布式系统,也是充斥着 tradeoff 。
使用前必须得能够接受这些 tradeoff,必要时还得调整自己的代码逻辑去适配。

楼主说的没错
但工程方面真的需要很多妥协,有人说为什么锁和队列都喜欢用 redis 。因为一般业务没那么大的场景,而且不一定都是钱相关
主要是 redis 简单,单机就能抗很大的流量
比如用 zk,实际用过就知道,本身服务故障的几率比 redis 大多了,有时候天生分布式反而是它的缺点,运维成本搞
队列也类似比如用 kafka 、RocketMQ 抛开本身集群的运维,还得知道很多概念,用错了问题更大,redis 的 LPUSH,RPOP 简单很多
这么说的,大部分工程师能把业务需求整明白就很不错了

> 首先单机排除
但实际 99% 场景都是用单机 redis 锁啊。
分布式锁是为了序列化多机器访问共享资源,多台机器访问一台 redis 的锁就不是分布式锁了?
如果 redis down 我大不了都 acquire lock 失败 -- 但纯用来锁的单机 redis 比你的 zk 集群稳多了。

说白了其实小公司根本没那么大的流量,根本不用管理什么集群。我很好奇,为什么不上云解决这个问题呢?那天业务暴增了也能扛得住。

选择了分布锁,基本是就是要求 CP 了,既然 CP 了,那么单机 redis 好像也没啥问题。所以,用单机 redis 实现分布锁总没问题了吧(不加超时)。
当然,尽量系统设计的时候就要避免分布式锁,超时导致的问题无解吧。

楼主说的好像并没有错,而且,既然都上了分布式锁,还要高并发?这过分了吧。
数据地带为您的网站提供全球顶级IDC资源