zoukankan      html  css  js  c++  java
  • 分布式锁

    1)锁的概念

    同步方式:

    • 原子变量
    • volatile

    锁的性能优化

    • 缩小锁的范围
    • 减小锁的粒度
    • 锁分段

    锁的分类

    • 公平锁:synchronized, ReentrantLock
    • 非公平锁: ReentrantLock, CAS(自旋锁)
    • 独享锁: synchronized, ReentrantLock
    • 共享锁:Semaphore

    2)分布式锁

    • 互斥性:在任意时刻只有一个客户端可以获取锁
    • 防死锁:即使有一个客户端持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁
    • 持锁人解锁:加锁与解锁必须为同一客户端,客户端自己不能把别人的加的锁给解开了
    • 可重入:当一个客户端获取对象锁后,这个客户端可以再次获取本对象上的锁

    A. Redis分布式锁

    1)加锁流程

    2)Redis分布式锁算法

    a. 加锁:
    • setnx命令,set if not exists
    • 设置锁的有效时间防止死锁
    • 设置一个随机值用来标识锁的持有人
    b. 解锁:
    • 检查是否持有锁
    • 删除锁
    c. 使用lua脚本保证解锁操作的原子性
    if redis.call("get", KEYS[1]) == ARGV[1]
    then return redis.call("del", KEYS[1])
    else return 0
    end 

    B. 基于数据库的分布式锁

    1)实现方式

    • 新建一张锁表
    • 获取锁时插入一条数据
    • 解锁时删除数据

    2)主要问题:

    • 可用性差,数据库挂掉会导致业务系统不可用,连接数量有限
    • 锁的失效时间难以控制,容易造成死锁
    • 非阻塞锁,未获得锁的线程需要需次出发获得锁操作
    • 非重入锁,同一个线程在没有释放锁之前无法再次获取该锁

    C. 基于zk的分布式锁

    1)实现方式:

    每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的临时有序节点。判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。

    当释放锁的时候,只需将这个临时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。

    2)主要问题:

    性能一般,加减锁的时候需要通过Leader创建或删除临时节点

    D.  分布式锁比较

    1)理解成本

    数据库 > 缓存 > Zookeeper

    2)复杂性

    Zookeeper > 缓存 > 数据库

    3)性能

    缓存 > Zookeeper > 数据库

    4)可靠性

    Zookeeper > 缓存 > 数据库

    3)幂等性

    处理幂等性常用的方法

    • A. 生成全局唯一id(uuid),借助redis存储
    • B. 乐观锁机制(cas)
    • C. 悲观锁机制(for update)?
    • D. Token机制(类全局id)
    • E. 防重表(支付订单号,唯一索引)
    • F. 异步处理
  • 相关阅读:
    Android自动化测试解决方案
    Oracle数据库的DML命令的处理过程详解
    Oracle数据库的BULK COLLECT用法之批量增删改
    建设DevOps能力,实现业务敏捷
    强大的C# Expression在一个函数求导问题中的简单运用
    Visual Studio 11开发者预览版发布(附下载)
    js table隔行变色
    编译原理语法推导树
    巧用数据库归档技术解决性能下降问题
    编译原理正规式和有限自动机
  • 原文地址:https://www.cnblogs.com/Terry-Wu/p/12578170.html
Copyright © 2011-2022 走看看