2024软考架构师考试---分布式锁的实现方式有那些以及优缺点

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
云原生网关 MSE Higress,422元/月
简介: 【6月更文挑战第16天】在分布式系统中,分布式锁是一种用于控制对共享资源访问的机制,以确保多进程、多线程环境下的数据一致性。分布式锁有多种实现方式,本文将介绍几种常见的分布式锁及其优缺点。

在分布式系统中,分布式锁是一种用于控制对共享资源访问的机制,以确保多进程、多线程环境下的数据一致性。分布式锁有多种实现方式,本文将介绍几种常见的分布式锁及其优缺点。

一、基于数据库的分布式锁

实现方式

  1. 表锁:使用数据库提供的锁机制,例如 MySQL 的 SELECT ... FOR UPDATE 语句。
  2. 乐观锁:使用版本号或时间戳字段进行并发控制。
  3. 悲观锁:在表中添加一个锁定状态字段,通过更新该字段实现锁定。

优点

  • 实现简单,易于理解。
  • 适合小规模的分布式系统和已有的数据库环境。

缺点

  • 性能较低,数据库的 IO 开销较大。
  • 存在单点故障问题,即数据库故障导致锁机制失效。
  • 扩展性差,不适合高并发场景。

示例代码(基于 MySQL 表锁)

sql复制代码

-- 创建锁表
CREATE TABLE `distributed_lock` (
    `resource` VARCHAR(64) NOT NULL PRIMARY KEY,
    `locked` TINYINT(1) NOT NULL DEFAULT 0,
    `owner` VARCHAR(64) NOT NULL
);

-- 获取锁
INSERT INTO distributed_lock (resource, locked, owner) VALUES ('resource_name', 1, 'node_id')
ON DUPLICATE KEY UPDATE locked = IF(locked = 0, 1, locked), owner = IF(locked = 0, 'node_id', owner);

-- 释放锁
UPDATE distributed_lock SET locked = 0 WHERE resource = 'resource_name' AND owner = 'node_id';

二、基于缓存(如 Redis)的分布式锁

实现方式

使用 Redis 的 SETNX 命令或 Redisson 等库实现分布式锁。

优点

  • 性能较高,Redis 作为内存数据库,读写速度快。
  • 支持高并发,适合大规模分布式系统。
  • 实现相对简单,社区有成熟的解决方案。

缺点

  • 存在单点故障问题,需要配置 Redis 集群或哨兵模式。
  • 需要额外的 Redis 依赖和运维成本。

示例代码(基于 Redis 的 SETNX

java复制代码

import redis.clients.jedis.Jedis;

public class RedisLock {

    private Jedis jedis;
    private String lockKey;
    private long lockTimeout;

    public RedisLock(Jedis jedis, String lockKey, long lockTimeout) {
        this.jedis = jedis;
        this.lockKey = lockKey;
        this.lockTimeout = lockTimeout;
    }

    public boolean tryLock(String value) {
        long end = System.currentTimeMillis() + lockTimeout;
        while (System.currentTimeMillis() < end) {
            if (jedis.setnx(lockKey, value) == 1) {
                jedis.expire(lockKey, (int) (lockTimeout / 1000));
                return true;
            }
            if (jedis.ttl(lockKey) == -1) {
                jedis.expire(lockKey, (int) (lockTimeout / 1000));
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        return false;
    }

    public void unlock(String value) {
        if (value.equals(jedis.get(lockKey))) {
            jedis.del(lockKey);
        }
    }
}

三、基于 Zookeeper 的分布式锁

实现方式

使用 Zookeeper 的临时有序节点(Ephemeral Sequential Nodes)实现分布式锁。

优点

  • 强一致性,Zookeeper 通过 Paxos 算法保证数据一致性。
  • 高可靠性,Zookeeper 集群提供高可用性。
  • 支持高并发,适合大规模分布式系统。

缺点

  • 实现复杂度较高,相比其他方式需要更多的配置和维护。
  • 性能不如 Redis,在极高并发下可能成为瓶颈。

示例代码(基于 Curator 框架)

java复制代码

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;

public class ZookeeperLock {

    private InterProcessMutex lock;

    public ZookeeperLock(CuratorFramework client, String lockPath) {
        this.lock = new InterProcessMutex(client, lockPath);
    }

    public void lock() throws Exception {
        lock.acquire();
    }

    public void unlock() throws Exception {
        lock.release();
    }
}

四、基于 Etcd 的分布式锁

实现方式

使用 Etcd 的分布式锁 API 或基于租约机制实现分布式锁。

优点

  • 高可用性,Etcd 提供高可用集群(Raft 协议)。
  • 强一致性,Etcd 保证数据一致性。
  • 适合云原生环境,Kubernetes 使用 Etcd 作为其数据存储。

缺点

  • 相对较新的技术,社区和文档支持不如 Zookeeper。
  • 实现复杂度较高,需要额外的 Etcd 依赖和配置。

示例代码(基于 Etcd Java 客户端)

java复制代码

import io.etcd.jetcd.Client;
import io.etcd.jetcd.lock.LockResponse;
import io.etcd.jetcd.options.PutOption;

public class EtcdLock {

    private Client client;
    private String lockKey;
    private long leaseId;

    public EtcdLock(Client client, String lockKey) {
        this.client = client;
        this.lockKey = lockKey;
    }

    public boolean lock() {
        try {
            leaseId = client.getLeaseClient().grant(5).get().getID();
            LockResponse response = client.getLockClient().lock(lockKey.getBytes(), leaseId).get();
            return response != null;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public void unlock() {
        try {
            client.getLockClient().unlock(lockKey.getBytes()).get();
            client.getLeaseClient().revoke(leaseId).get();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

比较与总结

锁实现方式 优点 缺点
数据库锁 实现简单,易于理解 性能低,存在单点故障,扩展性差
Redis 锁 性能高,支持高并发,社区支持好 存在单点故障,需额外依赖和运维成本
Zookeeper 锁 强一致性,高可靠性,适合大规模系统 实现复杂度高,性能可能成为瓶颈
Etcd 锁 高可用性,强一致性,适合云原生环境 实现复杂度高,相对较新,社区支持较少

不同的实现方式各有优缺点,具体选择哪种分布式锁实现方式,取决于具体应用场景及系统需求。对于高并发、高性能要求的场景,Redis 锁通常是不错的选择;而对于需要强一致性和高可靠性的场景,Zookeeper 或 Etcd 则更为适合。希望本文的介绍能帮助你在实际项目中更好地选择和应用分布式锁技术。



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
17天前
|
存储 边缘计算 Cloud Native
“论模型驱动架构设计方法及其应用”写作框架,软考高级,系统架构设计师
模型驱动架构设计是一种用于应用系统开发的软件设计方法,以模型构造、模型转换和精化为核心,提供了一套软件设计的指导规范。在模型驱动架构环境下,通过创建出机器可读和高度抽象的模型实现对不同问题域的描述,这些模型独立于实现技术,以标准化的方式储存,利用模型转换策略来驱动包括分析、设计和实现等在内的整个软件开发过程。
|
19天前
|
消息中间件 传感器 Cloud Native
事件驱动作为分布式异步服务架构
【6月更文挑战第25天】本文介绍事件驱动架构(EDA)是异步分布式设计的关键模式,适用于高扩展性需求。EDA提升服务韧性,支持CQRS、数据通知、开放式接口和事件流处理。然而,其脆弱性包括组件控制、数据交换、逻辑关系复杂性、潜在死循环和高并发挑战。EDA在云原生环境,如Serverless,中尤其适用。
42 2
事件驱动作为分布式异步服务架构
|
2天前
|
消息中间件 Java 开发者
Spring Cloud微服务框架:构建高可用、分布式系统的现代架构
Spring Cloud是一个开源的微服务框架,旨在帮助开发者快速构建在分布式系统环境中运行的服务。它提供了一系列工具,用于在分布式系统中配置、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态等领域的支持。
19 5
|
6天前
|
消息中间件 监控 Java
使用Kafka实现分布式事件驱动架构
使用Kafka实现分布式事件驱动架构
|
11天前
|
存储 关系型数据库 分布式数据库
PolarDB,阿里云的云原生分布式数据库,以其存储计算分离架构为核心,解决传统数据库的扩展性问题
【7月更文挑战第3天】PolarDB,阿里云的云原生分布式数据库,以其存储计算分离架构为核心,解决传统数据库的扩展性问题。此架构让存储层专注数据可靠性,计算层专注处理SQL,提升性能并降低运维复杂度。通过RDMA加速通信,多副本确保高可用性。资源可独立扩展,便于成本控制。动态添加计算节点以应对流量高峰,展示了其灵活性。PolarDB的开源促进了数据库技术的持续创新和发展。
154 2
|
19天前
|
存储 消息中间件 API
“论微服务架构及其应用”写作框架,软考高级,系统架构设计师
论微服务架构及其应用近年来,随着互联网行业的迅猛发展,公司或组织业务的不断扩张,需求的快速变化以及用户量的不断增加,传统的单块(Monolithic)软件架构面临着越来越多的挑战,已逐渐无法适应互联网时代对软件的要求。在这一背景下,微服务架构模式(MicroserviceArchitecturePattern)逐渐流行,它强调将单一业务功能开发成微服务的形式,每个微服务运行在一个进程中;采用HTTP等通用协议和轻量级API实现微服务之间的协作与通信。这些微服务可以使用不同的开发语言以及不同数据存储技术,能够通过自动化部署工具独立发布,并保持最低限制的集中式管理。
|
22天前
|
传感器 边缘计算 监控
边缘云作为一种分布式云计算架构,正在为多个行业和应用场景带来革命性的变化
边缘云应用于智能城市、工业物联网、零售、农业、AI、5G优化、制造、物流、医疗、交通和家居等领域,实现低延迟的数据处理、实时分析与优化。例如,智能交通利用边缘计算优化信号灯,减少拥堵;工业场景中,设备监控与预测性维护提升效率;在医疗中,实时监测患者数据支持远程诊断。此外,边缘云还助力零售业的个性化推荐、农业的精准作业和云游戏的高性能体验。
|
20天前
|
SQL 关系型数据库 MySQL
MySQL高可用架构设计:从主从复制到分布式集群
MySQL高可用性涉及主从复制、半同步复制和Group/InnoDB Cluster。主从复制通过二进制日志同步数据,保证故障时可切换。半同步复制确保事务在至少一个从服务器确认后才提交。Group Replication是多主复制,支持自动故障切换。InnoDB Cluster是8.0的集成解决方案,简化集群管理。使用这些技术能提升数据库的稳定性和可靠性。
216 2
|
4天前
|
监控 Java API
Java面试题:解释微服务架构的概念及其优缺点,讨论微服务拆分的原则。
Java面试题:解释微服务架构的概念及其优缺点,讨论微服务拆分的原则。
8 0
|
10天前
|
缓存 Devops 微服务
微服务01好处,随着代码越多耦合度越多,升级维护困难,微服务技术栈,异步通信技术,缓存技术,DevOps技术,搜索技术,单体架构,分布式架构将业务功能进行拆分,部署时费劲,集连失败如何解决
微服务01好处,随着代码越多耦合度越多,升级维护困难,微服务技术栈,异步通信技术,缓存技术,DevOps技术,搜索技术,单体架构,分布式架构将业务功能进行拆分,部署时费劲,集连失败如何解决