分布式锁的概念、应用场景、实现方式和优缺点对比

一:什么是分布式锁

分布式锁是一种用于协调分布式系统中多个节点对共享资源的访问的机制。在分布式系统中,由于多个节点的并发执行,可能会导致对共享资源的竞争,而分布式锁的目的就是确保在任何时刻,只有一个节点能够持有锁,从而避免对共享资源的冲突访问

分布式锁的设计考虑到以下问题:

  • 互斥性(Mutual Exclusion): 任意时刻只有一个节点能够持有锁。
  • 安全性(Safety): 即使持有锁的节点崩溃或发生其他故障,系统仍能够继续正常工作。
  • 活性(Liveness): 在没有故障发生的情况下,最终会有一个节点成功获取到锁。

二:使用分布式锁的场景

多台服务器中,同一套代码,只需要执行一次【定时任务等】

不同的节点可能会同时对共享资源进行操作,如果没有有效的措施,就会发生数据不一致的情况。例如,两个节点同时对同一个数据进行修改,如果没有严格的同步机制,就会导致数据出现覆盖或冲突的情况。

三:分布式锁的实现类型

  1. 基于数据库 (MySql等) 实现;
  2. 基于缓存(Redis等)实现;
  3. 基于Zookeeper 实现;
    ps:每种实现类型中都有不同实现方式 ,比如mysql有悲观锁和乐观锁的两种实现方式

基于zookeeper分布式锁,使用InterProcessMutex对象代码案例

相关依赖

xml 复制代码
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.3.0</version> <!-- 使用最新版本 -->
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.3.0</version> <!-- 使用最新版本 -->
</dependency>
java 复制代码
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;

public class DistributedLockExample {

    private static final String ZOOKEEPER_CONNECTION_STRING = "localhost:2181"; // 替换为实际的 ZooKeeper 服务器地址
    private static final String LOCK_PATH = "/example/lock"; //用于获取锁的zookeeper临时目录

    public static void main(String[] args) {
    
        CuratorFramework curatorFramework = createCuratorFramework();
        // 创建分布式锁对象
        InterProcessMutex lock = new InterProcessMutex(curatorFramework, LOCK_PATH);
        try {
            // 尝试获取锁,阻塞直到获取锁成功  参数1 等待时间   参数2 等待时间单位 
            lock.acquire(1,TimeUnit.SECONDS);
            // 在这里执行需要加锁的业务逻辑
            System.out.println("Locked code block");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放锁
                lock.release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 关闭 CuratorFramework 客户端
        curatorFramework.close();
    }
	//获取zookeeper连接
    private static CuratorFramework createCuratorFramework() {
        return CuratorFrameworkFactory.newClient(
                ZOOKEEPER_CONNECTION_STRING,
                new ExponentialBackoffRetry(1000, 3));
    }
}

四:优缺点对比

从性能角度(从高到低)来看:"缓存方式>Zookeeper方式>=数据库方式"。

  • 基于数据库实现分布式锁:

    优点:

    简单易实现,不需要引入额外的组件。

    使用数据库的事务特性,可以保证原子性。

    缺点:

    性能相对较差,因为每次加锁都要涉及到数据库的操作。

    可能会有死锁风险,需要谨慎处理事务隔离级别。

    对数据库的压力较大。

  • 基于缓存(Redis等)实现分布式锁:

    优点:

    性能较高,因为缓存系统通常能够提供快速的读写操作。

    可以设置锁的过期时间,避免死锁。

    缺点:

    对于分布式环境,需要确保缓存的高可用性。

    在某些情况下,可能会发生锁失效或过期的问题。

    不同缓存系统的实现方式和性能特性有差异。

  • 基于 ZooKeeper 实现分布式锁:

    优点:

    具备较好的一致性和可靠性,适用于需要高一致性的场景。

    可以利用 ZooKeeper 的顺序节点和监听机制实现较为复杂的锁管理。

    缺点:

    相对较为复杂,需要引入额外的组件。

    性能相对较低,ZooKeeper 的写入操作开销较大。

    部署和维护 ZooKeeper 集群可能较为复杂。

PS:文章如有不当之处,烦请后台私信,第一时间处理

相关推荐
没有bug.的程序员9 小时前
Gradle 构建优化深度探秘:从 Java 核心到底层 Android 物理性能压榨实战指南
android·java·开发语言·分布式·缓存·gradle
文艺倾年9 小时前
【强化学习&SWE】如何无容器化进行强化学习训练
人工智能·分布式·大模型
代码的知行者14 小时前
分布式任务调度系列 - PowerJob
分布式
无心水15 小时前
【任务调度:数据库锁 + 线程池实战】4、架构实战:用线程池 + SKIP LOCKED 构建高可用分布式调度引擎
人工智能·分布式·后端·spring·架构
Coder_Boy_16 小时前
Java高级_资深_架构岗 核心知识点(模块三:高并发)
java·spring boot·分布式·面试·架构
每天要多喝水16 小时前
zookeeper 的使用
分布式·zookeeper·云原生
十月南城18 小时前
Kafka生态深化——Schema与Connect、CDC入湖的链路与一致性挑战
分布式·kafka
陈 洪 伟18 小时前
大模型推理引擎vLLM(10): vLLM 分布式推理源码结构解析
分布式·vllm
Coder_Boy_18 小时前
Java高级_资深_架构岗 核心知识点全解析(通俗透彻+理论+实践+最佳实践)
java·spring boot·分布式·面试·架构
笨蛋不要掉眼泪19 小时前
Sentinel 热点参数限流实战:精准控制秒杀接口的流量洪峰
java·前端·分布式·spring·sentinel