【分布式系列】分布式锁的设计与实现

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术,jvm,并发编程 redis,kafka,Spring,微服务等
    • 常用开发工具系列:常用的开发工具,IDEA,Mac,Alfred,Git,typora 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 新空间代码工作室:提供各种软件服务,承接各种毕业设计,毕业论文等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.分布式锁的设计原则
    • 二.分布式锁的实现方式
      • 1.基于数据库的实现
      • 2.基于缓存的实现
      • 3.基于 ZooKeeper 的实现
    • 三.分布式锁的可重入性
    • 四.实现示例
    • 五.结论

在分布式系统中,多个进程或线程可能会同时访问共享资源。为了保证数据的一致性和完整性,需要一种机制来确保在任何时刻只有一个进程或线程能够访问特定的资源。这种机制被称为分布式锁。本文将探讨分布式锁的设计原则、实现方式以及如何实现可重入性。
在这里插入图片描述

一.分布式锁的设计原则

  1. 互斥性:在任意时刻,只有一个进程可以持有锁。
  2. 安全性:即使在系统发生故障的情况下,也不会出现死锁。
  3. 性能:锁的获取和释放操作应该尽可能快,以减少对系统性能的影响。
  4. 可扩展性:随着系统规模的扩大,锁的性能不应显著下降。

二.分布式锁的实现方式

1.基于数据库的实现

利用数据库的唯一索引特性,可以创建一个表来存储锁的信息。当需要获取锁时,尝试插入一条记录,如果插入成功,则认为获取了锁;如果插入失败(违反了唯一性约束),则等待或重试。

2.基于缓存的实现

使用 Redis 等缓存系统,可以利用其原子操作来实现分布式锁。例如,使用SETNX命令设置一个键,如果该键不存在,则操作成功,认为获取了锁;如果键已存在,则操作失败,需要等待或重试。

3.基于 ZooKeeper 的实现

ZooKeeper 是一个为分布式应用提供一致性服务的软件,它的节点可以用于实现分布式锁。通过创建一个临时顺序节点,所有试图获取锁的进程都在该节点下创建自己的临时顺序节点,谁的序号最小谁就获得锁。

三.分布式锁的可重入性

可重入性是指一个进程在持有锁的情况下,可以多次请求同一把锁而不会导致死锁的特性。实现可重入的分布式锁通常需要以下步骤:

  1. 识别当前进程:每个进程在请求锁时,需要有一个唯一标识。
  2. 记录锁的持有者:在锁的数据结构中记录持有者的标识和持有次数。
  3. 检查锁的持有者:当一个进程请求锁时,首先检查当前锁的持有者是否是该进程。
  4. 增加持有计数:如果是同一进程请求锁,则增加该进程的持有计数。
  5. 释放锁时减少计数:当进程释放锁时,减少持有计数,当计数减到 0 时,才真正释放锁。

四.实现示例

以下是一个使用 Redis 实现的简单分布式锁的伪代码示例:

import redis
import threadingclass DistributedLock:def __init__(self, redis_client, lock_key, timeout=10):self.redis_client = redis_clientself.lock_key = lock_keyself.timeout = timeoutself.held = Falseself.locks_held = 0def acquire(self):if self.held:self.locks_held += 1return Trueelse:unique_id = threading.current_thread().identresult = self.redis_client.set(self.lock_key, unique_id, ex=self.timeout, nx=True)if result:self.held = Trueself.locks_held = 1return Trueelse:return Falsedef release(self):if self.held and self.locks_held > 0:self.locks_held -= 1if self.locks_held == 0:self.redis_client.delete(self.lock_key)self.held = Falsedef __enter__(self):return self.acquire()def __exit__(self, exc_type, exc_val, exc_tb):self.release()# 使用示例
with DistributedLock(redis.StrictRedis(), 'my_lock_key') as lock:# 临界区代码pass

在这里插入图片描述

五.结论

分布式锁是确保分布式系统中数据一致性的关键技术。通过选择合适的实现方式和考虑可重入性,可以设计出既安全又高效的分布式锁。然而,分布式锁的使用也应谨慎,因为不当的使用可能会导致系统性能下降或产生死锁。在设计分布式系统时,应权衡使用分布式锁的利弊,并探索其他可能的解决方案,如使用无锁编程技术或乐观锁等。

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/37684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

steam社区加载异常、加载失败、无法加载、黑屏的解决方法

随着steam夏季特卖的临近,最近几天开启史低折扣的大作已经越来越少了,不过也并不是没有。最经典的知名大作文明6之前已经打到1折的骨折价了,没想到也能背刺,现在是新史低价0.5折11元,很多玩家入手后纷纷前往社区看新手…

ZABBIX-7.0LTS在线部署部署教程

ZABBIX-7.0LTS在线部署部署教程 环境: 操作系统: ubuntu 22.04zabbix-server版本: 7.0LTS系统配置[需结合监控的业务量提供配置]: 建议2C(CPU)8G(运行) 100GB(存储)架构:LNMP 第一步: 系统初始化 1.配置…

计算机网络知识整理笔记

目录 1.对网络协议的分层? 2.TCP/IP和UDP之间的区别? 3.建立TCP连接的三次握手? 4.断开TCP连接的四次挥手? 5.TCP协议如何保证可靠性传输? 6.什么是TCP的拥塞控制? 7.什么是HTTP协议? 8…

MySQL InnoDB支持几种行格式

数据库表的行格式决定了一行数据是如何进行物理存储的,进而影响查询和DML操作的性能。 在InnoDB中,常见的行格式有4种: 1、COMPACT:是MySQL 5.0之前的默认格式,除了保存字段值外,还会利用空值列表保存null…

快速傅里叶变换(Fast Fourier Transform,FFT)

快速傅里叶变换(Fast Fourier Transform,FFT)是一种算法,用于快速计算离散傅里叶变换(DFT)及其逆变换。傅里叶变换将时间或空间域的信号转换为频率域的信号,便于分析信号的频率特性。FFT显著提高…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-20填充与步幅

20填充与步幅 import torch from torch import nn# 此函数初始化卷积层权重,并对输入和输出提高和缩减相应的维数 def comp_conv2d(conv2d, X):# 这里的(1,1)表示批量大小和通道数都是1#将输入张量 X 的形状调整为 (1, 1, height,…

Grafana-11.0.0 在线部署教程

Grafana-11.0.0 在线部署教程 环境: 操作系统: ubuntugrafana版本: 11.0.0 (建议不要按照最新版)grafana要求的系统配置不高,建议直接部署在监控服务器上,比如zabbix服务器、prometheus服务器…

从菌群代谢到健康影响——认识肠道丙酸和丁酸

谷禾健康 短链脂肪酸这一词经常出现在谷禾的文章和报告中,那你真的了解短链脂肪酸吗?短链脂肪酸(SCFA)主要是肠道微生物群在结肠内通过发酵碳水化合物(包括膳食和内源性碳水化合物,主要是抗性淀粉和膳食纤维)和一些微生物可利用的蛋白质而产生…

光线追踪:原理与实现

版权声明 本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明文章内容不得删减、修改、演绎本文视频版本:见文末 各位同学大家好,今天我要给大家分享的是光线追踪的原理和实现大家知道在过往很多年里面&#x…

超简单的nodejs使用log4js保存日志到本地(可直接复制使用)

引入依赖 npm install log4js 新建配置文件logUtil.js const log4js require(log4js);// 日志配置 log4js.configure({appenders: {// 控制台输出consoleAppender: { type: console },// 文件输出fileAppender: {type: dateFile,filename: ./logs/default, //日志文件的存…

如何从0构建一款类似pytest的工具

Pytest主要模块 Pytest 是一个强大且灵活的测试框架,它通过一系列步骤来发现和运行测试。其核心工作原理包括以下几个方面:测试发现:Pytest 会遍历指定目录下的所有文件,找到以 test_ 开头或 _test.py 结尾的文件,并且…

python 实例002 - 数据转换

题目: 有一组用例数据如下: cases [[case_id, case_title, url, data, excepted],[1, 用例1, www.baudi.com, 001, ok],[4, 用例4, www.baudi.com, 002, ok],[2, 用例2, www.baudi.com, 002, ok],[3, 用例3, www.baudi.com, 002, ok],[5, 用例5, www.ba…

MS-Net: A Multi-Path Sparse Model for Motion Prediction in Multi-Scenes

MS-Net: A Multi-Path Sparse Model for Motion Prediction in Multi-Scenes 基本信息 期刊:IEEE ROBOTICS AND AUTOMATION LETTERS (IF 4.6 SCI3区)单位:同济大学,上海人工智能实验室时间:2023年12月数据…

架构师必知的绝活-JVM调优

前言 为什么要学JVM? 首先:面试需要 了解JVM能帮助回答面试中的复杂问题。面试中涉及到的JVM相关问题层出不穷,难道每次面试都靠背几百上千条面试八股? 其次:基础知识决定上层建筑 自己写的代码都不知道是怎么回事&a…

精准图像识别:算法与应用的双重突破

精准图像识别在近年来取得了算法与应用的双重突破,这些突破不仅推动了技术的发展,也极大地拓宽了图像识别的应用领域。以下是对这些突破的详细概述: 算法突破 深度学习技术的崛起:深度学习,特别是卷积神经网络&#…

C++中的虚函数表结构框架

一.虚函数表介绍 Virtual Table虚函数表是实现多态的 每个有虚函数的类的实现,都有个指向虚函数的指针表(不管是父类还是子类) 指向虚表的指针是作为数据成员存在实例对象中 当调用虚函数时,就去查找对象的虚表中指向整顿派生类函…

golang template HTML动态模板解析实现

使用场景: 我们希望在模板里面动态解析指定的模板文件。 这个似乎使用go语言的模板嵌套 template 可以实现,不过模板嵌套声明里面是不支持使用变量的, 如:{{template "模板文件名" .}} 这里的"模板文件名"不…

LeetCode 2710.移除字符串中的尾随零:模拟

【LetMeFly】2710.移除字符串中的尾随零:模拟 力扣题目链接:https://leetcode.cn/problems/remove-trailing-zeros-from-a-string/ 给你一个用字符串表示的正整数 num ,请你以字符串形式返回不含尾随零的整数 num 。 示例 1: 输…

Apache Kylin资源管理全指南:优化你的大数据架构

标题:Apache Kylin资源管理全指南:优化你的大数据架构 摘要 Apache Kylin是一个开源的分布式分析引擎,旨在为大规模数据集提供高性能的SQL查询能力。在Kylin中进行有效的资源管理对于确保查询性能和系统稳定性至关重要。本文将详细介绍如何…

leetcode 133双周赛 统计逆序对的数目「dp」「前缀和优化」

3193. 统计逆序对的数目 题目描述: 给定一个长度为n的二维数组 r e re re,其中 r e [ i ] [ i d i , c n t i ] re[i] [id_i, cnt_i] re[i][idi​,cnti​],求存在多少个全排列perm满足对所有的 r e [ i ] re[i] re[i]都有 p e r m [ 0.. …