icql

分布式基础_分布式锁

一、概述

分布式环境下,控制对共享资源的同步访问(资源访问的隔离性)

二、实现方案

1. redis

利用redis的数据隔离性(单线程执行有序),对redis中的共享资源进行操作

1) SETNX命令

SET:可以实现下面几个的命令
SETNX:key存在,不做任何动作,返回0;key不存在,设置成功,返回1
SETEX:相当于 SET key value,EXPIRE key seconds
PSETEX:和SETEX相似,不过单位是毫秒

2) Redisson框架

推荐此方案,Redisson部分源码

设置过期时间,执行完释放锁/按照过期时间释放锁
没有设置过期时间,执行完释放锁/默认按照30s续期(看门狗watchdog)

3) 问题

主从集群模式下,当在主节点获取到锁时,还没来得及同步到从节点,从节点重新被选举为主节点,会造成多个线程拿到锁

解决方案:

(1) redlock
>假设有5个redis节点
>这些节点之间既没有主从
>也没有集群关系
>客户端用相同的key和随机值在5个节点上请求锁
>请求锁的超时时间应小于锁自动释放时间
>当在3个(超过半数)redis上请求到锁的时候
>才算是真正获取到了锁。如果没有获取到锁
>则把部分已锁的redis释放掉

(2) 采用兼容redis协议的kv数据库(持久型)

推荐此方案

2. db

1) 典型表结构:
id 自增id
key 锁key(唯一索引)
holder 锁持有者
expire_time 过期时间

2) 操作
加锁lock, insert ingore key
解锁lock, delete key
定时扫描删除 expire_time < now 的数据