五种分布式锁(分布式锁实现方案)
ccwgpt 2024-10-31 12:32 49 浏览 0 评论
序
- 什么是分布式锁?
- 基于数据库的分布式锁(一)
- 基于缓存的分布式锁——Redis锁(二)
- 基于ZooKeeper的分布式锁(三)
- 基于分布式算法的锁(如基于Raft或Paxos的锁)四
- 基于文件锁的分布式锁(五)
- 用Go+Lua实现基于Redis的分布式锁
- Raft算法是什么?
- 基于文件锁的分布式锁如何实现?
- ……
开始吧~~
什么是分布式锁?
分布式锁(Distributed Lock)是一种用于在分布式系统中协调多个进程或线程访问共享资源的同步机制。它的主要目的是确保在分布式环境下,同一时刻只有一个进程或线程可以访问共享资源,以防止数据竞争和不一致性问题。
一、两个关键操作:
- 获取锁:进程或线程尝试获取锁以访问共享资源。如果锁是可用的,获取锁的操作成功,该进程或线程可以访问资源。如果锁已被其他进程或线程获取,尝试获取锁的操作会被阻塞或失败。
- 释放锁:进程或线程在使用完共享资源后,释放锁,使其他进程或线程能够获取锁并访问资源。
二、要求和特性:
- 互斥性:同一时刻只有一个进程或线程可以获得锁,确保资源的独占性。
- 可重入性:允许已经持有锁的进程或线程重新获取该锁,以防止死锁。
- 超时机制:支持设置锁的超时时间,以防止锁被长时间占用。
- 容错性:在分布式系统中,要能够处理节点故障、网络分区等异常情况,以确保锁的可用性。
- 高性能:锁的实现应尽量减少性能开销,以适应高并发的情况。
分布式锁在分布式系统中用于协调资源访问、任务调度、避免并发问题等方面发挥着重要作用。
基于数据库的分布式锁(一)
一、特点:
使用数据库表的行或记录来表示锁,利用数据库的事务支持来实现锁的获取和释放。
二、优势:
持久性好,可靠性高,适用于需要持久性的锁。
三、劣势:
性能相对较低,可能引起数据库负载,不适用于高并发情况。
基于缓存的分布式锁——Redis锁(二)
一、特点:
使用缓存服务器(如Redis)来存储锁信息,通过缓存的原子操作来获取和释放锁。
二、优势:
性能较高,支持自动过期,适用于高并发环境,易于部署。
三、劣势:
可能存在锁的不可重入性,需要处理锁的过期问题。
基于ZooKeeper的分布式锁(三)
一、特点:
使用ZooKeeper这种分布式协调服务来实现锁管理,利用ZooKeeper的顺序节点来确定锁的获取顺序。
二、优势:
具有强一致性,适用于复杂的分布式协作场景,支持公平锁。
三、劣势:
相对复杂,性能不如缓存锁。
四、代码示例:
package main
import (
"github.com/samuel/go-zookeeper/zk"
"time"
)
var zkServers = []string{
"zookeeper-server-1:2181",
"zookeeper-server-2:2181",
"zookeeper-server-3:2181",
}
var conn *zk.Conn
func init() {
var err error
conn, _, err = zk.Connect(zkServers, time.Second)
if err != nil {
panic(err)
}
}
// 获取锁
func acquireLock(lockPath string) (*zk.Lock, error) {
lock := zk.NewLock(conn, lockPath, zk.WorldACL(zk.PermAll))
if err := lock.Lock(); err != nil {
return nil, err
}
return lock, nil
}
// 释放锁
func releaseLock(lock *zk.Lock) {
lock.Unlock()
}
// 使用锁
func main() {
lockPath := "/my_lock"
lock, err := acquireLock(lockPath)
if err != nil {
panic(err)
}
// 成功获取锁,执行需要锁定的代码
// 释放锁
releaseLock(lock)
}
基于分布式算法的锁(如基于Raft或Paxos的锁)四
一、特点:
使用分布式一致性算法来实现锁管理,通常需要专门的分布式系统架构。
二、优势:
提供强一致性,适用于分布式系统中需要高度可靠性的场景。
三、劣势:
复杂度较高,性能开销大。
基于文件锁的分布式锁(五)
一、特点:
使用分布式文件系统或共享文件来实现锁管理,需要文件系统的支持。
二、优势:
可靠性高,适用于需要持久性的场景。
三、劣势:
性能较低,依赖于文件系统的性能和可用性。
用Go+Lua实现基于Redis的分布式锁
使用 Redis 的 SETNX 命令来尝试获取锁,并使用 Lua 脚本来安全地释放锁。
package main
import (
"fmt"
"github.com/go-redis/redis"
"time"
)
var redisClient *redis.Client
func init() {
redisClient = redis.NewClient(&redis.Options{
Addr: "localhost:6379", // Redis服务器地址
Password: "", // 密码,如果有的话
DB: 0, // Redis数据库编号
})
}
func acquireLock(key string, value string, expiration time.Duration) (bool, error) {
result, err := redisClient.SetNX(key, value, expiration).Result()
return result, err
}
func releaseLock(key string, value string) error {
script := `
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
`
return redisClient.Eval(script, []string{key}, value).Err()
}
func main() {
lockKey := "my_lock"
lockValue := "my_value"
expiration := 10 * time.Second
// 尝试获取锁
locked, err := acquireLock(lockKey, lockValue, expiration)
if err != nil {
fmt.Println("Error acquiring lock:", err)
return
}
if locked {
// 成功获取锁
fmt.Println("Lock acquired")
// 执行需要加锁的代码
// 释放锁
err := releaseLock(lockKey, lockValue)
if err != nil {
fmt.Println("Error releasing lock:", err)
} else {
fmt.Println("Lock released")
}
} else {
// 未能获取锁
fmt.Println("Failed to acquire lock")
}
}
Raft算法是什么?
Raft(Raft Consensus Algorithm)是一种分布式一致性算法,用于在分布式系统中实现一致性和可用性。旨在解决分布式系统中的一致性问题,尤其是在分布式存储系统中的应用非常广泛。
Raft算法的设计目标是提供更容易理解和实现的一致性算法,相对于之前的Paxos算法来说,更容易被普通开发人员理解和应用。Raft算法的核心思想是通过选举机制,将系统中的节点分为领导者(leader)、跟随者(follower)和候选者(candidate)三种角色,其中领导者负责提出提案、复制日志和处理客户端请求,而跟随者和候选者则遵循领导者的指令。
Raft算法的关键特点包括:
- 领导者选举:Raft通过定期的选举过程来选出领导者,只有领导者才能接受客户端的请求。如果领导者宕机或失去联系,会触发新一轮选举,确保系统中仍然有领导者。
- 日志复制:领导者负责提出日志项(log entries),并将它们复制到其他节点的日志中,以确保数据的一致性。
- 安全性:Raft算法被设计为拥有良好的安全性属性,能够防止多种故障情况下的数据丢失和不一致性问题。
- 易于理解和实现:相对于一些更复杂的一致性算法,如Paxos,Raft的设计更为直观和容易理解,这使得它更适合教育和应用开发。
基于文件锁的分布式锁如何实现?
分布式文件锁是一种分布式锁的实现方式,它使用共享文件系统来协调多个进程或节点对共享资源的访问。
- 选择合适的共享文件系统:首先,你需要选择一个支持分布式文件共享的文件系统,例如NFS(Network File System)、Ceph、GlusterFS等。这个文件系统应该能够被多个节点访问,并且提供文件锁机制。
- 创建共享锁文件:在共享文件系统上创建一个专门用于锁的文件,例如一个空的占位文件。这个文件将用于表示锁的状态。
- 获取锁:当进程或节点需要获取锁时,它会尝试在共享文件系统上创建一个特定的锁文件,如一个临时文件,以表示锁的获取。你可以使用文件系统提供的原子创建文件的操作来实现这一步。
- 检查锁状态:在尝试创建锁文件后,进程需要检查共享文件系统中的锁文件的状态。如果锁文件已存在,表示锁已被其他进程或节点占用,当前进程需要等待或执行相应的锁冲突解决策略。
- 释放锁:当进程或节点不再需要锁时,它会删除在共享文件系统上创建的锁文件,以释放锁。这将使其他进程能够获取锁。
- 处理锁的过期和故障情况:需要考虑处理锁的过期问题,以防止锁被长时间占用。此外,还需要处理共享文件系统的故障或节点故障等异常情况,确保锁的可用性。
实际的分布式文件锁实现可能会更复杂,因为它需要处理分布式系统中的各种问题,如网络分区、节点故障、锁的竞争等。
我为人人,人人为我,美美与共,天下大同。
#妙笔生创作挑战##程序员##程序员经验分享##计算机##编程##分布式存储##IT##本地达人计划##一张图告别十月#
相关推荐
- 滨州维修服务部“一区一策”强服务
-
今年以来,胜利油田地面工程维修中心滨州维修服务部探索实施“一区一策”服务模式,持续拓展新技术应用场景,以优质的服务、先进的技术,助力解决管理区各类维修难题。服务部坚持问题导向,常态化对服务范围内的13...
- 谷歌A2A协议和MCP协议有什么区别?A2A和MCP的差异是什么?
-
在人工智能的快速发展中,如何实现AI模型与外部系统的高效协作成为关键问题。谷歌主导的A2A协议(Agent-to-AgentProtocol)和Anthropic公司提出的MCP协议(ModelC...
- 谷歌大脑用架构搜索发现更好的特征金字塔结构,超越Mask-RCNN等
-
【新智元导读】谷歌大脑的研究人员发表最新成果,他们采用神经结构搜索发现了一种新的特征金字塔结构NAS-FPN,可实现比MaskR-CNN、FPN、SSD更快更好的目标检测。目前用于目标检测的最先...
- 一文彻底搞懂谷歌的Agent2Agent(A2A)协议
-
前段时间,相信大家都被谷歌发布的Agent2Agent开源协议刷屏了,简称A2A。谷歌官方也表示,A2A是在MCP之后的补充,也就是MCP可以强化大模型/Agent的能力,但每个大模型/Agent互为...
- 谷歌提出创新神经记忆架构,突破Transformer长上下文限制
-
让AI模型拥有人类的记忆能力一直是学界关注的重要课题。传统的深度学习模型虽然在许多任务上取得了显著成效,但在处理需要长期记忆的任务时往往力不从心。就像人类可以轻松记住数天前看过的文章重点,但目前的...
- 不懂设计?AI助力,人人都能成为UI设计师!
-
最近公司UI资源十分紧张,急需要通过AI来解决UI人员不足问题,我在网上发现了几款AI应用非常适合用来进行UI设计。以下是一些目前非常流行且功能强大的工具,它们能够提高UI设计效率,并帮助设计师创造出...
- 速来!手把手教你用AI完成UI界面设计
-
晨星技术说晨星技术小课堂第二季谭同学-联想晨星用户体验设计师-【晨星小课堂】讲师通过简单、清晰的语言描述就能够用几十秒自动生成一组可编辑的UI界面,AIGC对于UI设计师而言已经逐步发展成了帮助我们...
- 「分享」一端录制,多端使用的便捷 UI 自动化测试工具,开源
-
一、项目介绍Recorder是一款UI录制和回归测试工具,用于录制浏览器页面UI的操作。通过UIRecorder的录制功能,可以在自测的同时,完成测试过程的录制,生成JavaScr...
- APP自动化测试系列之Appium介绍及运行原理
-
在面试APP自动化时,有的面试官可能会问Appium的运行原理,以下介绍Appium运行原理。Appium介绍Appium概念Appium是一个开源测试自动化框架,可用于原生,混合和移动Web应用程序...
- 【推荐】一个基于 SpringBoot 框架开发的 OA 办公自动化系统
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍oasys是一个基于springboot框架开发的OA办公自动化系统,旨在提高组织的日常运作和管理...
- 自动化实践之:从UI到接口,Playwright给你全包了!
-
作者:京东保险宋阳1背景在车险系统中,对接保司的数量众多。每当系统有新功能迭代后,基本上各个保司的报价流程都需要进行回归测试。由于保司数量多,回归测试的场景也会变得重复而繁琐,给测试团队带来了巨大的...
- 销帮帮CRM移动端UI自动化测试实践:Playwright的落地与应用
-
实施背景销帮帮自2015年成立以来,移动端UI自动化测试的落地举步维艰,移动端的UI自动化测试一直以来都未取得良好的落地。然而移动互联网时代,怎样落地移动端的UI自动化测试以快速稳定进行移动端的端到端...
- 编写自动化框架不知道该如何记录日志吗?3个方法打包呈现给你。
-
目录结构1.loguru介绍1.1什么是日志?程序运行过程中,难免会遇到各种报错。如果这种报错是在本地发现的,你还可以进行debug。但是如果程序已经上线了,你就不能使用debug方式了...
- 聊聊Python自动化脚本部署服务器全流程(详细)
-
来源:AirPython作者:星安果1.前言大家好,我是安果!日常编写的Python自动化程序,如果在本地运行稳定后,就可以考虑将它部署到服务器,结合定时任务完全解放双手但是,由于自动化程序与平...
- 「干货分享」推荐5个可以让你事半功倍的Python自动化脚本
-
作者:俊欣来源:关于数据分析与可视化相信大家都听说自动化流水线、自动化办公等专业术语,在尽量少的人工干预的情况下,机器就可以根据固定的程序指令来完成任务,大大提高了工作效率。今天小编来为大家介绍几个P...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)