分布式锁
2020-12-11 16:37:08 0 举报
AI智能生成
分布式锁
作者其他创作
大纲/内容
背景
锁
多个线程同时操作同一共享变量时,会导致数据异常。需要对变量做加锁控制,控制请求依次访问
解决多个线程同时访问集群共享资源
要求
互斥性
高可用
可重入
死锁机制
非阻塞锁
实现
MySQL
乐观锁 version
在数据库业务表里添加 version 字段
每次更新时先查询到该条记录的 version 字段的值,更新的时候,把 version 作为条件更新
主键冲突
加锁:添加指定主键值记录
释放锁:删除指定主键值记录
悲观锁
加锁:使用SELECT for UPDATE加锁
释放锁:释放事务 connection.commit();
Redis
单机
加锁:使用setnx key value[ThreadID+UUID] expressTime
防止业务线程未完成,key提前过期。守护线程:定时判断业务线程未指且过期时间<=设置时间 重置key过期时间
释放锁:业务线程完成后,获取当前key对应的value值,删除本线程的key
集群
RedLock
半数成功
Zookeeper
ZNode
临时节点(EPHEMERAL)
临时顺序节点(EPHEMERAL_SEQUENTIAL)
有顺序、客户端断开会自动删除的节点
持久节点(PERSISTENT)
持久顺序节点(PERSISTENT_SEQUENTIAL)
Watches
客户端在节点上设置Watches,当节点状态发生变化时,监视器被触发通知客户端
公平锁
准备:每个客户端创建临时有序 节点
加锁:客户端获取节点列表,判断自己为序列最小的节点获取锁成功,其余客户端监听小于自己的前一个节点
原子性:当判断自己节点不为第一个节点,要添加对前一个节点的监听时,上个节点删除。所以需要读取节点和添加监听动作的原子性
释放锁:客户端执行完后断开连接,节点自动删除,Watch通知下个节点,下个节点的客户端判断自己是否为第一个节点。重复
[每个连接都是session,session会使用心跳检测连接是否正常]
非公平锁
准备:每个客户端创建临时 节点
加锁:zk创建临时节点,多个client只能有一个创建成功。创建成功的获取锁。其余client Watch成功节点
释放锁:客户端执行完后断开连接,节点自动删除,Watch通知其他client竞争锁
羊群效应:当释放锁后所有等待进程一起来创建节点,并发量很大。
对比
MySQL
优点:实现简单
缺点:并发性能差、事务超时
并发:悲观锁select for update在事务中利用数据库行锁或表锁,并发问题严重
Redis
优点:高并发
缺点:实现复杂、无锁等待机制
Zookeeper
优点:有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。实现起来较为简单。
缺点:并发性低于redis,实现原理是动态创建、销毁临时节点。ZK集群中只有Leader才能创建和删除节点
无锁化编程
经过Nginx负载均衡相同reqid的请求将被转发到一台机器上
线程池的管理者Disper按照reqid哈希取模来进行多线程的负载均衡
0 条评论
下一页