微信搜索【程序员囧辉】,关注这个坚持分享技术干货的程序员。
我的最新文章:全网最硬核 Redis 大厂面试题解析(2021年最新版)
前言
分布式锁无论是在实际应用,还是面试中,都是经常会遇到的,因此很有必要掌握这个知识点。
今天跟大家一起探讨下当前主流的几种实现方案及其优缺点。
正文
为什么需要锁
原因其实很简单:因为我们想让同一时刻只有一个线程在执行某段代码。
因为如果同时出现多个线程去执行,可能会带来我们不想要的结果,可能是数据错误,也可能是服务宕机等等。
以淘宝双11为例,在0点这一刻,如果有几十万甚至上百万的人同时去查看某个商品的详情,这时候会触发商品的查询,如果我们不做控制,全部走到数据库去,那是有可能直接将数据库打垮的。
这个时候一个比较常用的做法就是进行加锁,只让1个线程去查询,其他线程待等待这个线程的查询结果后,直接拿结果。在这个例子中,锁用于控制访问数据库的流量,最终起到了保护系统的作用。
再举个例子,某平台做活动“秒杀茅台”,假如活动只秒杀1瓶,但是同时有10万人在同一时刻去抢,如果底层不做控制,有10000个人抢到了,额外的9999瓶平台就要自己想办法解决了。此时,我们可以在底层通过加锁或者隐式加锁的方式来解决这个问题。
此外,锁也经常用来解决并发下的数据安全方面的问题,这里就不一一举例了。
为什么需要分布式锁
分布式锁是锁的一种,通常用来跟 JVM 锁做区别。
JVM 锁就是我们常说的 synchronized、Lock。
JVM 锁只能作用于单个 JVM,可以简单理解为就是单台服务器(容器),而对于多台服务器之间,JVM 锁则没法解决,这时候就需要引入分布式锁。
实现分布式锁的方式
实现分布式锁的方式其实很多,只要能保证对于抢夺“锁”的系统来说,这个东西是唯一的,那么就能用于实现分布式锁。
举个简单的例子,有一个 MySQL 数据库 Order,Order 库里有个 Lock 表只有一条记录,该记录有个状态字段 lock_status,默认为0,表示空闲状态,可以修改为1,表示成功获取锁。
我们的订单系统部署在100台服务器上,这100台服务器可以在“同一时刻”对上述的这1条记录执行修改,修改内容都是从0修改为1,但是 MysQL 会保证最终只会有1个线程修改成功。因此,这条记录其实就可以用于做分布式锁。
常见实现分布式锁的方式有:数据库、Redis、Zookeeper。
这其中又以 Redis 最为常见。