自学八股:分布式锁基础

前置知识

分布式系统,一个后端服务会与多个客户端进行连接,所以会有负载均衡,多线程和异步这些情况 由于SpringBoot项目中内置Tomcat,所以处理一般都是多线程的

主要在项目的任务领取功能的部分使用了分布式锁

  • 在分布式系统中,分布式锁 是一种用于协调多个进程或线程对共享资源访问的机制。它主要用于解决在高并发场景下对共享资源的竞争问题,确保在任意时刻只有一个客户端可以操作共享资源。
  • 在分布式系统中,某些任务可能需要确保在任意时刻只有一个实例在运行。分布式锁可以防止多个实例同时执行相同的任务。
  • 在分布式系统中,多个客户端可能会同时对数据库或缓存进行写操作。如果没有适当的同步机制,可能会导致数据不一致。 在某些场景下,需要确保在读取和写入共享资源时的原子性。分布式锁可以防止多个客户端同时进行读写操作,从而保证数据的一致性。
  • 在分布式系统中,多个客户端可能会同时对共享数据进行操作。如果没有适当的同步机制,可能会导致数据竞争,从而导致数据不一致。

这个项目为什么要使用分布式锁:防止任务超领;

ps: 要区分线程锁和分布式锁,像java中实现的synchronized和Lock,线程锁本质是基于线程之间的共享内存实现的

实际使用

分布式锁的核心就是大家共用一把锁,这样就可以锁住线程,不让线程进行,让程序串行化执行,在实际中通过Mysql,Redis,Zookpeer都可以,但是在项目中主要使用的是用Redis实现分布式锁,所以这里主要探讨利用Redis实现分布式锁

1,基于SETNX实现分布式锁

获取锁:

  • 互斥 :每次只能有一个线程获得锁
  • 非阻塞:尝试一次,成功返回true,失败返回false 释放锁:
  • 手动释放
  • 超时释放
  • 保证故障的时候依然可以释放锁,避免出现死锁

这个实现的锁可以基于lua脚本进行进一步的改进,保证锁的原子性,并负担解锁的任务

2,基于RedLcok实现分布式锁

假设有两个服务A、B都希望获得锁,有一个包含了5个redis master的Redis Cluster,执行过程大致如下:

  1. 客户端获取当前时间戳,单位: 毫秒
  2. 服务A轮寻每个master节点,尝试创建锁。(这里锁的过期时间比较短,一般就几十毫秒) RedLock算法会尝试在大多数节点上分别创建锁,假如节点总数为n,那么大多数节点指的是n/2+1。
  3. 客户端计算成功建立完锁的时间,如果建锁时间小于超时时间,就可以判定锁创建成功。如果锁创建失败,则依次(遍历master节点)删除锁。
  4. 只要有其它服务创建过分布式锁,那么当前服务就必须轮寻尝试获取锁。

3,基于Redission实现

优势:

  1. redission的所有指令都是基于lua脚本实现,保证了操作的原子性
  2. redission设置了watchdog看门狗,看门狗的逻辑保证了没有死锁发生
  3. redisson支持RedLock的实现方式

如何使用

  1. 线程去获取锁,获取成功: 执行lua脚本,保存数据到redis数据库。
  2. 线程去获取锁,获取失败: 订阅了解锁消息,然后再尝试获取锁,获取成功后,执行lua脚本,保存数据到redis数据库

互斥,可重入,watch dog后面再具体说

总结:

这就是一些分布式锁的基础知识,之前面试的时候,面试官问这里问的非常多,但是当时没太懂,甚至把分布式锁说成了线程锁(哈哈)

相关推荐
wuyikeer22 分钟前
Spring Framework 中文官方文档
java·后端·spring
Victor35627 分钟前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor35636 分钟前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer1 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP2 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪
人间打气筒(Ada)2 小时前
如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
开发语言·后端·golang
开心就好20252 小时前
使用Wireshark进行TCP数据包抓包分析:三次握手与四次挥手详解
后端·ios
用户4419395054872 小时前
OpenClaw服务器部署保姆级教程
后端
zdl6862 小时前
springboot集成onlyoffice(部署+开发)
java·spring boot·后端
Soofjan2 小时前
sync.Mutex讲解
后端