这篇分布式锁解读,能否算得上第二?

本文探讨了分布式锁在多线程并发场景下的重要性,详细介绍了分布式锁的定义、要求以及常见的实现方式,包括基于数据库、ZooKeeper和Redis。针对每种实现方式,文章列举了其优缺点,并提供了实现原理。最后,提出了在不同部署环境下选择合适分布式锁策略的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

对多线程有所了解的朋友一般都会熟悉一个概念:锁。

在多线程并发场景下,要保证在同一时刻只有一个线程可以操作某个业务、数据或者变量,通常需要使用加锁机制。比如synchronizedLock等。

而随着架构演进、业务发展,我们的应用往往都不是只部署在一台服务器上,而是使用分布式集群架构,同时存在多台相同的应用。

比如某电商网站在进行商品销售时,因为商品的数量是有限的,每个用户购买一件商品,需要将商品的库存减1;

但是我们想一下,在“双十一”这种火爆的活动时,可能会有大量的用户购买同一件商品,同时对该商品库存减1,如果不加锁,则极有可能会造成商品超卖情况。

要保证在这种分布式场景下,共享数据的安全性和一致性,则需要使用分布式锁。上面例子中的商品库存就是共享数据。

什么是分布式锁

顾名思义,分布式锁是指在分布式场景下,保证同一时刻对共享数据只能被一个应用的一个线程操作。用来保证共享数据的安全性和一致性。

分布式锁应该满足哪些要求

现在我们来分析一下,我们要实现一个分布式锁的话,需要满足哪些要求呢?

  • 首先最基本的,我们要保证同一时刻只能有一个应用的一个线程可以执行加锁的方法,或者说获取到锁;(一个应用线程执行
  • 然后我们这个分布式锁可能会有很多的服务器来获取,所以我们一定要能够高性能的获取和释放;(高性能
  • 不能因为某一个分布式锁获取的服务不可用,导致所有服务都拿不到或释放锁,所以要满足高可用要求;(高可用
  • 假设某个应用获取到锁之后,一直没有来释放锁,可能服务本身已经挂掉了,不能一直不释放,导致其他服务一直获取不到锁;(锁失效机制,防止死锁
  • 一个应用如果成功获取到锁之后,再次获取锁也可以成功;(可重入性
  • 在某个服务来获取锁时,假设该锁已经被另一个服务获取,我们要能直接返回失败,不能一直等待。(非阻塞特性

以上是所有分布式锁要满足的一些基本要求。

实现方式有哪些

那么我们可以采取哪种方式来实现分布式锁呢?目前常见的方式主要有以下三种:

  • 基于数据库实现
  • 基于ZooKeeper实现
  • 基于Redis实现

接下来我们看看这三种方式具体都是怎样实现分布式锁的。

基于数据库

使用数据库实现分布式锁,有两种方式。

第一种是基于数据库表实现。

比如我们有如下表来保存分布式锁记录:

CREATE TABLE `methodLock` ( 
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',  
    `method_name` varchar(64) NOT NULL COMMENT '锁定的方法名',
    `desc` varchar(1024) NOT NULL DEFAULT '备注信息',
    `update_time` timestamp NOT NULL DEFAULT now() ON UPDATE now() COMMENT '保存时间',  
    PRIMARY KEY (`id`),
    UNIQUE KEY `uidx_method_name` (`method_name `)
) ENGINE=InnoDB COMMENT='分布式锁定的方法';

当我们的某个服务要执行某段需要分布式锁定的方法时,则执行插入语句,在该表中插入一条记录。

insert into methodLock(method_name,desc) values 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黑说Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值