阅读文本大概需要3分钟。
0x01、基于mysql实现分布式锁
基于分布式锁的实现,首先肯定是想单独分离出一台mysql数据库,所有服务要想操作文件(共享资源),那么必须先在mysql数据库中插入一个标志,插入标志的服务就持有了锁,并对文件进行操作,操作完成后,主动删除标志进行锁释放,其与服务会一直查询数据库,看是否标志有被占用,直到没有标志占用时自己才能写入标志获取锁。
但是这样有这么一个问题,如果服务(jvm1)宕机或者卡顿了,会一直持有锁未释放,这样就造成了死锁,因此就需要有一个监视锁进程时刻监视锁的状态,如果超过一定时间未释放就要进行主动清理锁标记,然后供其与服务继续获取锁。
如果监视锁字段进程和jvm1同时挂掉,依旧不能解决死锁问题,于是又增加一个监视锁字段进程,这样一个进程挂掉,还有另一个监视锁字段进程可以对锁进行管理。这样又诞生一个新的问题,两个监视进程必须进行同步,否则对于过期的情况管理存在不一致问题。
因此存在以下问题,并且方案变得很复杂:
监视锁字段进程对于锁的监视时间周期过短,仍旧会造成多售(jvm1还没处理完其持有的锁就被主动销毁,造成多个服务同时持有锁进行操作)。
监视锁字段进程对于锁的监视时间周期过长,会造成整个服务卡顿过长,吞吐低下。
监视锁字段进程间的同步问题。
当一个jvm持有锁的时候,其余服务会一直访问数据库查看锁,会造成其余jvm的资源浪费。
0x02、基于Redis实现分布式锁
相比较于基于数据库实现分布式锁的方案来说,基于缓存来实现在性能方面会表现的更好一点,Redis就是其中一种。由于Redis可以设置字段的有效期,因此可以实现自动释放超期的锁,不需要多个监视锁字段进程进行锁守护,可以依旧存在上述mysql实现中除了3以外1、2、4中的问题。
0x03、基于Zookeeper实现分布式锁
基于以上两种实现方式,有了基于zookeeper实现分布式锁的方案。由于zookeeper有以下特点:
维护了一个有层次的数据节点,类似文件系统。
有以下数据节点:临时节点、持久节点、临时有序节点(分布式锁实现基于的数据节点)、持久有序节点。
zookeeper可以和client客户端通过心跳的机制保持长连接,如果客户端链接zookeeper创建了一个临时节点,那么这个客户端与zookeeper断开连接后会自动删除。
zookeeper的节点上可以注册上用户事件(自定义),如果节点数据删除等事件都可以触发自定义事件。
zookeeper保持了统一视图,各服务对于状态信息获取满足一致性。
Zookeeper的每一个节点,都是一个天然的顺序发号器。
猜你还想看
领取专属 10元无门槛券
私享最新 技术干货