自学八股:分布式锁基础

前置知识

分布式系统,一个后端服务会与多个客户端进行连接,所以会有负载均衡,多线程和异步这些情况 由于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后面再具体说

总结:

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

相关推荐
橘猫云计算机设计2 小时前
基于Springboot的自习室预约系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·后端·毕业设计
秋书一叶2 小时前
SpringBoot项目打包为window安装包
java·spring boot·后端
pwzs3 小时前
Spring MVC 执行流程全解析:从请求到响应的七步走
java·后端·spring·spring mvc
小兵张健3 小时前
互联网必备职场知识(4)—— 共情沟通能力
后端·产品经理·运营
AskHarries4 小时前
使用 acme.sh 自动更新 SSL 证书的指南
后端
Chandler244 小时前
Go:反射
开发语言·后端·golang
pwzs4 小时前
深入浅出 MVCC:MySQL 并发背后的多版本世界
数据库·后端·mysql
盒子69104 小时前
go for 闭环问题【踩坑记录】
开发语言·后端·golang
刘大猫265 小时前
Arthas monitor(方法执行监控)
人工智能·后端·监控
追逐时光者6 小时前
MongoDB从入门到实战之MongoDB简介
后端·mongodb