分布式锁设计

1.分布式锁定义:

分布式环境下,锁定全局唯一资源, 请求处理串行化,实际表现互斥锁

2.分布式锁目的

2.1.交易订单锁定

防止重复下单

解决业务层幂等问题  

2.2.MQ消息消费幂等性

发送消息重复

消息消费端去重

比如手机提现 

2.3.在用户对商品下单后,订单状态为待支付,在某一时刻用户正在对该订单做支付操作,商家对该订单进行改价操作

状态的修改行为需要做串行处理,避免出现数据错乱

3.基于Redis分布式锁

redis特点:唯一线程串行处理。

3.1.实现方案

Redis Setnx(SET if Not exists)命令在指定的key不存在时,为key设置指定的值

         SETNX Key_name value Expire Time

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

3.2.存在问题:

       锁时间不可控

            无法续租期

       单点问题:

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

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

   3.3. 官方建议

           Redis本身建议使用RedLock算法来保证,但是问题是需要至少三个Redis主从实例来完成,维护成本相对较高。

           Redlock等同于自己实现简单的一致性协议,细节繁锁,且容易出错。

总结:Redis本身是AP模型,所以在严格需要一致性时,这种方案不适用。

4.高可用分布式锁设计目标

4.1.设计目标:

4.1.1.强一致性

4.1.2.服务高可用,系统稳健

4.1.3.代码高度抽象业务接入极简

4.1.4.可视化管理后台,监控及管理

4.2..存储产品对比

设计分布式锁需要基于分布式存储,

存储产品对比 

redis: 一致性 : 无; CAP: AP; 高可用:主从;接口类型:客户端;实现:setNX

zookeeper:一致性:paxos ; CAP:CP; 高可用:N+1可用;接口类型:客户端;实现:createEphemeral

etcd:一致性:raft; CAP:CP/AP; 高可用:N+1可用;接口类型:http/grpc; 实现: restful API

总结:1)、由于Redis无法保证数据的一致性

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

          3)、最终选择基于etcd实现

5.etcd介绍:

5.1.简单kv

5.2.强一致

5.3.高可用, 无单点

5.4.数据高可靠,持久化

6.分布式锁整体方案

6.1. 分布式Client + etcd

         Client TTL模式

6.2. Client TTL模式

      假设有两个客户同是拿锁 : key:锁的id,  ttl为时间 , vlue:随意;uuid:不需要填,在拿锁成功后,etcd会成uuid,代表锁的唯一凭证,要对锁进行操作需要提供uuid
        ClientA -> etcd ->("key", "ttl", "value", "uuid")

        ClientB -> etcd ->("key", "ttl", "value", "uuid")

   etcd保存只有一个线程拿到锁, 如 clientA拿锁成功, ClientB拿锁失败

   A服务需要对etcd保持后台心跳线程, 比如:key的租期10ms,后台心跳线程为3ms,心跳线程负责在拿到key之后每3ms cas唯一凭证uuid, 每3ms钟会将租期修改为10ms

6.3.使用场景

6.3.1.业务方申请资源锁,调用提供key, ttl

         如 key:order id , ttl:10ms

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

6.3.3.检查etcd中此key 是否存在,如没有尝试写入key, 写入失败,拿锁失败,写入成功拿锁成功

6.3.4.拿锁后,心跳线程启动,心跳线程维持时间为ttl/3, compare and swap uuid,从而将key值续租

6.3.5.相关etcd api

7.etcd兼容性测试

etcd提供了独有的集群管理模式,方便进行极端case下的测试,以三个节点为的etcd集群为例:

1)、单节点停机,不影响持续写入,不影响读,结果有一致性

2)、当只有一个节点时,读会停机,写入正常

3)、理论上只要不是多节点同时停机,线上服务不会受影响

8.etcd恢复/版本

8.1.etcd自有数据恢复方式:如果服务停机后,可以将所有数据转移后重启

8.2.etcd的增删节点 ,节点迁移等部署相关,均有相关操作方式 

8.3.etcd版本选择,选择使用etcd3.2.9但是因为V3API暂时还不够完备,建议使用V2方式实现 

     V3提供gRPC接口

      天然提供分布式锁功能

            只需要申请锁,释放锁

             不用关注锁的租期问题

9.分布锁特殊场景 

9.1.特殊场景 一:

    分布式锁只是在同一自然时间的互斥锁,本身不解决幂等性问题

             接入业务需要完善从获得锁到释放锁中间数据幂等逻辑

9.2.特殊场景二:锁没有按照预期续租

     心跳续租没成功  

      马上启动GC,GC时间够长

 9.3.特殊场景三:etcd内部协调发生问题

            leader节点挂了,选主中,是拿不到锁

            Raft日志数据同步发生错误 或者不一致问题

以上情况可能需要做2套分布式锁

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值