分布式锁

分布式锁主要用于在分布式环境中保护跨进程、跨主机、跨网络的共享资源实现互斥访问,以达到保证数据的一致性。前几天看到有个技术群里的同行在问分布式锁的问题,说是被面试官各种***难。疫情影响下,各行各业都挺卷,面试官的意思很明确,你有造火箭的经验吗,有的话去他们公司造自行车,如果没有,今天的面试就到这里了。


 

设计分布式锁

  • 分布式系统环境下,一个方法在同一时间只能被一台机器的一个线程执行

  • 高性能、高可用的获取锁与释放锁

  • 可重入

  • 具备锁失效机制,防止死锁

  • 阻塞特性


 

 

▎基于数据库的实现

    核心思想:在数据库中创建一个表,表中包含资源名等字段,并在资源名字段上创建唯一索引,想要获取某个资源,就使用资源名向表中插入数据,成功插入则获取锁,执行完成后删除对应行的数据释放锁。

 

 

 

 

  • 基于数据库实现的,数据库的可用性和性能将直接影响分布式锁的可用性及性能,所以数据库需要双机部署、数据同步、主备切换。适用于对锁的性能要求不高的场景

  • 锁失效机制,有可能出现成功插入数据后,服务器宕机,对应的数据没有被删除,当服务恢复后一直获取不到锁。可以在表中新增一列,用于记录失效时间,并需要开启定时任务清除失效的数据


 

▎基于Redis的实现

 

  • 产生随机字符串RandomStr,执行SET PX NX,返回1,则获得锁

  • Redis2.6.12以前版本可使用lua脚本打包SETNX,EXPIRE保持原子操作

  • 开启守护线程,在最大续期次数内,间隔时间进行锁续期

  • 完成业务后,释放RandomStr对应的锁


 

▎基于Zookeeper的实现

 

 

 

 

 

 

 

  • 线程A在/distribute_lock下创建临时顺序节点

  • 线程A获取/distribute_lock下的全部节点并排序,如果线程A创建的节点是最小节点,则获得锁;如果不是,则监听比自己次小的节点

  • 比自己次小的节点发生变更(删除),重复执行第二步

  • 业务执行完毕,删除节点,释放锁

  • 为什么没使用单节点创建互斥来实现:避免引发羊群效应,带来瞬时并发问题。比如1000个节点需要同步,当节点释放锁时,其余999个节点会同时收到通知并尝试创建节点,可能引起性能问题


 

    相比Redis,Zookeeper实现不需要担心锁超时时长的设置和续期问题,但需要频繁的创建和删除节点,性能上不如Redis,可根据具体场景选择适合的实现方式。

 

posted @ 2022-03-21 15:46  萧小满  阅读(51)  评论(0编辑  收藏  举报