news 2026/4/14 23:45:31

19.分布式锁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
19.分布式锁

在一个分布式系统中,涉及到多个节点访问同一个公共资源的情况,此时就需要通过锁来做互斥控制,避免出现类似于“线程安全”问题。
之前学过的锁本质都只能在一个进程内部生效,分布式系统是有很多进程的(每个服务器都是独立的进程),之前的锁是无法实现进程间的制约。

1.分布式锁场景

两个客户端同时去查询,都查到了余票为1,都执行--操作,最终使得票数剩余-1,这就导致超卖了;

所谓的分布式锁,本质也是一个/一组单独的服务端程序,给其他服务器提供“加锁”这样的服务,给其他服务器提供“加锁”这样的服务(Redis是一种典型实现分布式锁的方案,不是唯一一种);

买票服务器,在进行买票操作过程中,需要先加锁(往redis上设置一个特殊的key-value,完成上述买票操作之后,删除);

setnx可以实现加锁效果,针对解锁,使用del命令完成;
问题:进程内部的锁,进程退了,锁就没了;但是分布式的锁,如果持有锁的服务器掉电,会导致锁无法释放,其他服务器就无法获取到锁了?

解决方法:给set的key设置过期时间,一旦时间到,key就会被自动删除;
需要用:set ex nx这种来设置,如果用setnx+expire,这是无法保证原子的;

问题:如果一个服务器加锁,另一个给它解了?

解决:引入校验机制
1)给服务器编号,每个服务器有一个自己的身份标识;解锁时先查询编号,相同才del;
2)加锁时,设置key-value,key要对应针对哪个资源加锁,value存储服务器编号;

问题:加入了校验机制后,必须要两步才能完成,一步查询、一步del,但这两步操作不能保证是原子的。


虽然看起来这两个服务器执行两次del没有问题,但是如果有第3个服务器,在B执行del前就加锁了,就会把这个锁解了;
解决:引入lua脚本,用lua写一些逻辑,上传到redis服务器上,然后让客户端来控制redis执行上述脚本,redis执行lua的过程,也是原子的(redis官方文档:lua是事务的替代方案);

2.过期时间续约问题

问题:加锁时,设置过期时间多少合适?
设置多了,服务器挂了,很久才释放;
设置少了,服务器还没操作完就自动解锁了;
解决:动态续约,例如:初始设置1s,等到剩余300ms,再把时间续成1s,从此往复;
因此服务器这边需要一个专门的线程来负责续约,这个线程被称为“看门狗”(watch dog);

3.redis挂了

解决:采用主从+哨兵,进行加锁,把key设置到主节点上,主节点挂了,哨兵自动把从节点升级成主节点,进一步保证锁可用;
衍生问题:主从节点数据同步是存在延时的,主节点先收到set还没同步呢就挂了,从节点就没锁了;

解决:redlock算法,采用多组(主从+哨兵);
加锁就按照一定顺序,针对这些组redis加锁,写入key成功超过一半,视为加锁成功;
解锁时,上述主节点都进行一遍解锁;

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 12:41:27

深入解析 virsh console:KVM虚拟化中的文本控制台魔法

引言:当VNC无能为力时 在KVM虚拟化运维中,你是否遇到过这样的困境?虚拟机网络配置错误导致SSH连接中断,操作系统启动卡在GRUB界面,或者需要在无图形界面的服务器上进行紧急修复。这时,virsh console 就成了…

作者头像 李华
网站建设 2026/4/14 11:33:42

3.4 Deployment控制器详解:实现应用滚动更新和回滚策略

Deployment控制器详解:实现应用滚动更新和回滚策略 引言 Deployment 是 Kubernetes 中最常用的控制器,用于管理无状态应用。本文将深入讲解 Deployment 的工作原理,包括滚动更新、回滚策略、扩缩容等核心功能,通过实战案例让你掌握生产级应用部署。 一、Deployment 基础…

作者头像 李华
网站建设 2026/4/11 23:08:02

书匠策AI:毕业论文的“智能外挂军团”,六大功能颠覆你的写作认知

对于无数毕业生而言,毕业论文堪称“学术生涯的终极BOSS战”——选题撞车、逻辑混乱、查重不过、格式抓狂……这些问题像游戏关卡中的隐藏陷阱,稍有不慎就会前功尽弃。但如今,一款名为书匠策AI的智能工具正以“学术外挂军团”的姿态登场&#…

作者头像 李华
网站建设 2026/4/14 11:10:32

3.8 无状态应用迁移实战:将HTTP服务器平滑迁移到Kubernetes

无状态应用迁移实战:将HTTP服务器平滑迁移到Kubernetes 引言 将应用迁移到 Kubernetes 是云原生转型的关键步骤。本文将完整演示如何将 Go HTTP 服务器从 Docker 容器平滑迁移到 Kubernetes 平台,包括部署、服务暴露、监控等完整流程。 一、迁移准备 1.1 迁移检查清单 ✅…

作者头像 李华
网站建设 2026/4/9 2:25:49

基于MQTT通讯UNIapp程序解析JSON数据

1、解析函数无法解析{“ligh”:0010}不规范的JSON数//解析函数无法解析{“ligh”:0010}不规范的JSON数据if (e.method receive) {//e 是 MQTT 事件对象,e.method 表示事件类型。当接收到 MQTT 消息时,method 的值是 receivetry {//try 语句开始一个错误…

作者头像 李华