分布式锁

分布式环境下,锁定全局唯一资源

  • 请求处理串行化

  • 实际表现互斥锁

 

基于Redis分布式锁

  • 唯一线程串行处理

实现方式

Setnx命令指定的Key不存在时,为Key设置指定的值

SETNX KEY_NAME VALUE Expire_time

设置成功,返回1,设置失败返回0

 

存在的问题

  • 锁时间不可控,无法续租期

  • 单点问题

    • 单实例存在进程一旦死掉,会彻底阻塞业务流程

    • 主从方式,主从数据异步,会存在锁失效的问题

官方建议

Redis本身建议使用Redlock算法保证,类似RAFT,等同自己实现简单的一致性问题,细节繁琐,且容易出错

 

redis分布式锁本质是AP模型,主从同步时半同步,可能出错。对高一致性要求性不高的情况下可以使用

 

 

 

redis

zookeeper

etcd

一致性算法

paxos->ZAB

raft

CAP

AP

CP

CP/AP

高可用

主从

N+1可用(奇数个,投票选举时)

N+1可用

接口类型

客户端

客户端

http/grpc

实现

setNX

createEphemeral

restful API

redis无法保证数据一致性

Zookeeper 对锁实现使用创建临时节点和watch机制,执行效率,扩展能力,社区活跃度等低于etcd

 

etcd

简单KV

强一致

高可用

数据高可靠,持久化

 

分布式锁整体方案

分布式客户端+etcd

Client TTL模式

 

Client A->etcd->(key,ttl,value,uuid)

Client B->etcd->(key,ttl,value,uuid)

ClientA拿锁成功,ClientB拿锁失败

A服务需要对etcd保持后台心跳线程

比如key的租期为10ms,后台心跳线程为3ms,心跳线程负责在拿到key以后,没3ms cas唯一凭证uuid

业务申请资源锁,调用时提供key,ttl

etcd生成uuid,作为当前锁的唯一凭证,将key,uuid,ttl写入etcd

检查etcd中key是否存在,如没有尝试写入key

拿锁后,心跳线程启动,心跳线程维持时间为ttl/3,key续租 comapre and swap uuid

 

etcd API

申请锁

curl http://127.0.0.1:2379/v2/keys/foo XPUT -d value=bar ttl=5 prevExist=false

CAS更新锁续租

curl http://127.0.0.1:2379/v2/keys/foo?prevValue=prev_uuid XPUT -d value=bar ttl=5 refresh=true

CAS删除锁

curl http://127.0.0.1:2379/v2/keys/foo?prevValue=prev_uuid -XDELETE

如果调用方正常结束,通过cas接口调用delete方法自动清理etcd中的key值

如果调用方异常终止,等待原有锁ttl过期后,锁资源释放

 

etcd分V2,V3两个版本

V3文档不够完全,提供gRPC接口

天然提供分布式锁功能,只需要申请锁,释放锁,不需要关注锁的租期问题

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值