MySQL分布式锁
利用MySQL的特性:主键或者唯一索引值是唯一的。
Redis分布式锁
原理
使用setnx key value,setnx = set if not exists,也就是只有当key不存在时才set,key存在时不做任何操作。
获取锁:setnx key value
释放锁:del key
死锁
死锁举例:一个程序获取锁后,在执行业务逻辑的时候挂掉了,没有释放锁。其他程序就无法再获取该锁,会造成死锁。
死锁解决办法:设置key的过期时间 setnx key value ttl,value是请求的唯一标识
设置过期时间导致的问题:程序还没有执行完,锁过期了。这时就会有其他程序获取到锁,删除锁的时候也可能会删除其他程序的锁。
设置过期时间导致的问题的解决办法:
- 应用程序每隔半分钟使用自己的 watch dog 监测当前 key 的 value,如果仍然是自己,TTL再续一分钟;
- 应用程序在删除锁的时候,需要比较 value 的值是否和自己设置的相同
性能提升
使用分段锁,将资源分段
集群的问题
主从同步有延时,程序访问不同主机,会有问题。
解决方案:红锁
服务器之间不同步数据,服务器数量为奇数,应用程序需要在超过一半的机器上加锁成功。