百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

分布式锁最全详解(图文全面总结)

mhr18 2024-12-10 13:57 25 浏览 0 评论

分布式锁在分布式系统经常都会使用到,下面重点详解分布式锁的原理与实现@mikechen

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

什么是分布式锁?

分布式锁:是一种用于在分布式系统中实现互斥访问的机制,在分布式系统加锁,这就是分布式锁。

为什么需要分布式锁?

在传统的单机部署中,可以使用Java的ReentrantLock或Synchronized关键字进行互斥控制。

如下图所示:

但是,在分布式系统中,由于多个节点分布在不同的机器上,传统的锁机制在这种情况下失效,所以,需要分布式锁来解决。

如下图所示:

通过分布式锁,可以有效的解决跨JVM的互斥机制,从而,保证了数据的一致性和正确性。

因此,分布式锁成为了分布式系统中,解决共享资源访问问题的重要机制。

分布式锁的特点

首先为了确保分布式锁可用,我们至少要确保分布式锁的实现,同时满足以下3个条件。

1.互斥性

分布式锁:确保在任意时刻只有一个客户端能够获取锁,从而避免多个客户端同时访问共享资源导致的数据竞争和数据不一致性问题。

只有获取到锁的客户端才能对共享资源进行操作,其他客户端需要等待锁的释放。

2.避免死锁

分布式锁通常支持客户端多次获取锁而不会出现死锁的情况,即同一个客户端在持有锁的情况下可以重复获取锁,而不会被阻塞。

这样可以避免在复杂业务场景下出现死锁的情况,提高系统的稳定性和可靠性。

3.高可用性

分布式锁通常具有高可用性,能够在分布式系统中保持可用状态,即使在节点故障或网络分区等异常情况下也能够正常工作。

分布式锁的实现方式

分布式锁的实现方式,常见有3种,如下图所示:

主要会包含:数据库分布式锁、Redis实现分布式锁、以及Zookeeper实现分布式锁。

1.基于数据实现分布式锁

要实现分布式锁,最简单的方式可能就是直接创建一张锁表,如下图所示:

当我们想要锁住某个方法时,执行以下SQL,如下所示:

使用数据库作为锁的存储介质,可以利用数据库自身的事务处理和锁机制,使得实现分布式锁相对简单。

但是,使用数据库分布式锁可能会引入较大的性能开销,特别是在高并发情况下,频繁地进行数据库操作可能成为系统的瓶颈。

所以,一般我们都不会采用这种方式,而是会考虑使用Redis来实现分布式锁。

2.Redis分布式锁实现

为什么会采用Redis来是实现分布式锁呢,原因很简单,数据库性能不太好。

很显然,内存的性能会远远大于数据库么,而内存里面用的最多就是:Redis。

Redis 实现分布式锁,主要就会涉及到获取锁和释放锁。

第一步:获取锁

SET key value [EX seconds] [PX milliseconds] [NX|XX]
  • 如果该键不存在,则设置成功,获得了锁,设置过期时间来防止锁死。
  • 如果该键已存在,表示锁已被其他客户端持有,获取锁失败,需要等待或重试。

第二步:解锁

客户端通过 DEL 命令删除锁对应的键,可以释放锁。

也可以,通过 Lua 脚本在一次原子操作中判断键值并删除,确保释放锁的原子性。

如下所示:

-- 检查锁是否存在并且是当前客户端持有的
if redis.call("GET", KEYS[1]) == ARGV[1] then
    -- 如果是当前客户端持有的锁,则删除它
    redis.call("DEL", KEYS[1])
    return 1 -- 表示成功释放锁
else
    return 0 -- 表示锁已被其他客户端获取或已过期
end

假设锁的键是作为 KEYS[1] 传递的,脚本首先检查锁是否存在,并且它是由当前客户端持有的。

如果是,则删除锁并返回成功释放的信号,否则返回失败的信号。

3.ZooKeeper分布式锁实现

Zookeeper 分布式锁的实现,主要是基于 临时顺序节点来实现的。

如下图所示:

主要会包含如下步骤:

1.创建一个 ZNode 作为锁的根节点

在 ZooKeeper 中,分布式锁通常通过创建一个临时有序节点来实现。

首先,在 ZooKeeper 中创建一个根节点来表示锁。例如,/locks。

2.尝试获取锁

当某个客户端想要获取锁时,它会在 /locks 节点下创建一个顺序临时节点,例如 /locks/lock-000000001,创建节点的顺序由 ZooKeeper 自动分配。

客户端检查自己创建的节点是否是当前 /locks 节点下最小的节点,如果是,则表示该客户端获取了锁,否则,它需要监听前一个节点的变化事件。

3.释放锁

当客户端完成了它的任务后,它会删除自己创建的节点,释放锁。

以上

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

相关推荐

说说Redis的单线程架构(redis的单线程模型)

一句话总结Redis采用单线程处理命令请求,避免了多线程的上下文切换和锁竞争,保证原子性操作。其基于内存的高效执行和I/O多路复用模型支撑了高并发性能。网络I/O和持久化操作(如RDB/AOF)由后台...

答记者问之 - Redis 的高效架构与应用模式解析

问:极客程序员你好,请帮我讲一讲redis答:redis主要涉及以下核心,我来一一揭幕Redis的高效架构与应用模式解析Redis是一个开源的内存数据存储系统,因其高性能、丰富的数据结构和易用性...

Redis的5种核心数据结构,及其最经典的“应用场景”

Redis凭什么稳坐缓存界头把交椅?全靠这五个“身怀绝技”的数据结构!在分布式系统的江湖里,Redis就像一位身怀绝技的武林高手,而它的五大核心数据结构正是克敌制胜的五套绝学。今天咱们就来拆解这些独门...

精准定位文件包含漏洞:代码审计中的实战思维

前言最近看到由有分析梦想cms的,然后也去搭建了一个环境看了一看,发现了一个文件包含漏洞的点,很有意思,下面是详细的复现和分析,以后代码审计又多了一中挖掘文件包含漏洞的新思路环境搭建下载https...

ARDM:一款国产跨平台的Redis管理工具

ARDM(AnotherRedisDesktopManager)是一款免费开源的Redis桌面管理客户端,支持Windows、Mac、Linux跨平台。功能特性ARDM提供的主要功能如...

SpringBoot的Web应用开发——Web缓存利器Redis的应用!

 Web缓存利器Redis的应用Redis是目前使用非常广泛的开源的内存数据库,是一个高性能的keyvalue数据库,它支持多种数据结构,常用做缓存、消息代理和配置中心。本节将简单介绍Redis的使...

Windows服务器部署CRMEB开源电商系统,详细教程来了!

安装PHP已经安装过PHP的可以跳过首先安装VC运行库下载地址https://docs.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redi...

Windows系统下Redis各个安装包介绍与选择指南

简介Redis作为高性能的键值数据库,广泛应用于缓存、消息队列等场景。在Windows系统中部署Redis时,用户可以选择多种安装包以满足不同的需求。本文将详细介绍以下Redis8.0.3版本的安装...

从面试题入手,深度剖析Redis Cluster原理

揭开RedisCluster的神秘面纱**在当今数字化浪潮中,数据量呈爆炸式增长,应用程序对数据存储和处理的要求也日益严苛。Redis作为一款高性能的内存数据库,凭借其出色的读写速度和丰富的数...

给大家推荐些好的c语言代码的网站

C语言,那就来推荐几个吧,部分含有C++:1、TheLinuxKernelArchives(kernel.org)Linux内核源码,仅限于C,但内核庞大,不太适合新手;2、redis(redi...

Redis String 类型的底层实现与性能优化

RedisString是Redis中最基础也是应用最广泛的数据类型,它能存储文本、数字、二进制数据等多种形式的信息。深入理解其底层实现对构建高性能分布式系统至关重要。Redis字符串的底层结...

阿里面试问:Redis 为什么把简单的字符串设计成 SDS?

分享了一道面阿里的redis题,我看了以后觉得挺有意思。题目大致是这样的面试官:了解redis的String数据结构底层实现嘛?铁子:当然知道,是基于SDS实现的面试官:redis是用C语言开发的,那...

编程语言那么多,为何C语言能成为最成功的语言?

编程语言那么多,为何C语言能成为最成功的语言?2025年嵌入式岗位暴增47%,新人却还在问"C语言过时了吗"。真相是连机器人关节驱动都得靠它写,不会指针连芯片手册都看不懂。见过用Pyt...

go-zero 使用 redis 作为 cache 的 2 种姿势

在go-zero框架内,如在rpc的应用service中,其内部已经预置了redis的应用,所以我们只需要在配置中加入相关字段即可,另外,在svcContext声明redisc...

Redis事务深度解析:ACID特性、执行机制与生产实践指南

一、Redis事务的本质与核心机制Redis事务通过MULTI、EXEC、WATCH等命令实现,其本质是将多个命令序列化后一次性执行,而非传统数据库的严格事务模型。核心特点如下:命令队列化:MULT...

取消回复欢迎 发表评论: