00:00
Hello,伙伴们大家好,我是坚持日更的世根,今天给大家分享的文章是分布式锁如何实现?嗯,分布式是我们现在比较主流的技术,常常和微服务一起出现,那么对于多个实例之间,我们如何保证就是每个进程和线程之间是同步共享资源的呢?我们首先可能会一想到锁,我们认知里面这个S,包括Python里面洛克,它只是单机的时候解决这种并发性的问题,就是我们常说的线程安全性的问题,但是在分布式环境下他们就不起作用了,我在实习的时候呢,也遇到这样的一个问题,那么今天这篇文章呢,我会给带大家。讲解实现分布式锁的主要的三种方式。那么就是首先给大家吃个瓜吧,就是有一天下班的时候啊,我看到的就是这样的一个新闻,就是。
01:00
超额售卖这个,呃,演唱会的门票的事情,我当时一想到就是这个超卖问题嘛,这个是我也是我们在外面试的之后常常问到的超外问题怎么解决,呃,我当时就是易经这个是,呃,应该是加锁嘛,实现这种分布式锁,我们把实现分布式锁之后,这种问题就可以解决了,所以本着就是发现问题立马去解决的心态呢,我就立马去啊,写了这么一篇文章。在实现分布式锁之前,我们首先了解一下分布式锁是什么?就是分布式锁,它比较官方的概念一样,就是分布式锁是一种用于保持分布式系统中各个进程和线程访问共同资源的技术。我们可以把它理解成就是单机情况下,我们要保证多个线程呃去共享资源,那么现在的话,我们升级到的就是集群啊,多个分布式系统之间,他们要保呃守护同一个资源。
02:02
嗯,所以对于锁他们都是共性的,他们首先就要互斥性,就是任何时刻只内一个客户端持有锁,呃,就是锁抢占的,不管怎么抢占,只有一个,任何时刻只有一个客户端能够持有锁,有一个进程或者锁,那不会产生死锁,就是循环等待嘛,我们产生一个死锁,然后容错性的。就是容容忍这种节点故障的啊,比方说我们在分布在分布式环境下,我们是用的MYSQL集群或者red集群,能够容忍它的主从不一致。那么目目前业界主流的三种方式呢,就是实然是呃,基于数据库实现啊,就是说我们MYSL啊,我们可以使用那个乐管锁闭关锁来实现这种分布式锁,那么第二种呢,是用这个zoo keepper,那么zoo keepper它是也就是我们业界出身的铲屎官,它是一种高可用的这种分布式协调服务啊,我们也把它当做这种注册中心来使用,那么需要注意的是,它是CP理论的,就是说我们强励制性的。
03:07
最后一种就是我们现在主流的用到这个red实现分布式锁,也就是我们呃。常用的这种,它具有高可用的高科用性,那么下面呢,就是我们讲到它的具体实现,那我们看一下MY搜狗,可能悲关锁我们用的比较少,就是背关锁,我们可以理解为就是不管谁来操作,我们先上一把锁啊,等你这个操作完了我们再放锁啊,那么对应的代码呢,可以是就是这样的,就是我们,呃,比方说我们首先去,就我们可能会上面的代码,可能大家有点看不懂,就是我去查询用户的时候,我为什么还要加锁,那我们看一下下面这个代码就知道了,就首先我们要去查这个用户,如果用户不存在的时候,我们才去,呃,这个更新啊,如果。用户不存在的时候呢,我们就。
04:00
不不更新,并且扔出来一个异常,那么这里面就是这个选择的时候,就是去查询的时候去给他加把锁,避免就是我去。查的时候呢,正好有一个人去添加了啊,查完之后呢,正好别的县城去添加了这个,呃,就是查完之后别的县城去添加了这个用户,就导致了我们自己查的这个用户,呃,他比方说不存在,其实已经存在了,就导致这会出现这种数据重复的问题,其实这种这种就是并发性的问题呢,需要我们有这样一个去就是模拟思考一下这种重要的过程啊。第二种乐观锁,乐观锁其实就是我们常说的加一个版本号,无论是我是更新的或者删除啊,我们就加一个版本号去判断,那么这一点我之前在使用这个electric search的时候也遇到过,就是electric search,它也是通过这种version版本号去管理数据的更新和删除的。那么在我这个time米尔time米尔这个soql里面呢,我们是这样的,就是我去更新name的时候,让他的version加一,那么在就是在做更新之前,我们需要有一个条件嘛,我们首先要ID等于这个,并且version是等于我们传入那个,那么这下面代码可以一目了然,就是我需要三个参数,这个ID,这个LA,第三个就是version,那么首先需要根据I,呃,就是。
05:22
根据ID查itd,查完之后,如果这个用户存在的话,我们就去把它的LA和这个version传递进去,传递进去作为参数和作为产品的参数,和这个更新数据的数据。可以看到就是MASGO的话,它实现分布式锁的话,其实是相对简单的啊,也不需要我们额外的维护成本,但是我们需要考虑一下,就是既然我们都上分布式了啊,我们同一个服务部署在多个机器上的,那究竟是为什么,为了是我们这个性能的提升,是不是在我们这个负载均衡,那么这样的话,我们服务的压力小了,但是我们DB的压力就大了,我们买搜的数据我们知道是存在这个呃,磁盘上的,我们每一次查数据啊,或者是更新数据,我们都需要从磁盘上把数据写内存中,内存中操作完了之后写到磁盘上去,所以我们DP的这个IO的压力就会变大,那么第二个就是租keepper实现。
06:18
那么Su keepper呢,它是我刚才也提到过,它是CP,就是强一致性的理论,强一致性的,那么它对一些高可用的,高可用的这个高性能呢,高可用的强一致性的呃,服务可以使用它,呃,目前的话啊,我暂时还没有接触到过这样项目,所以我在这篇文章分享里面就把它略过了。那么最后一种就是我们常见到red reddi的话,我们会用到这个reddi这个组件,那么它里面带了一个redlo,就是我们俗称的这个红色,那么就可以很好的实现这种锁机制,其实我们如位看这个代码好,就非常像我们在单机情况下使用这个Java啊,自带的这个lock锁一样,我们首先就是获得锁啊,在锁这个里面进行TRY和finally操作啊,Finally里面我们就是去删除自己的锁嘛,我们把这个锁删除,嗯。
07:12
然后在这个Cha里面,我们尝试去操作这个数据,就保证了我们所有的这个非原子性的操作都在这个所中间去操作的。嗯,最后呢,我总结一下,就是我们常还是比较常用的red组keepper啊,就是首先他们的数据的存储方式不一样,就是red我们知道数据是存在内存中的,但是这个zoo keepper它的节点是放在这种按磁盘上的,比较占空间,那么锁的释放。上面呢,Red锁是设置过期时间,它去自动释放的,Keepper锁呢是要我们手动的释放,如果就是我们网络宕机啊,或者是这种。呃,网络中断的就会导致这个锁长长长长时间的不能够释放,嗯,第三个就是锁竞争机制,我们知道ROS是那个单机锁啊,就是所有的请求达到一台服务器啊,就是我们容易出现这种单联故障,但z keepper是分布式锁,因为我们提到它是CP的强一制型,就是我们达到任一台机上它数据都是一致的,也就是我们提到了下面这个一致型,那么是严格是分布式锁,多个进程到同一个,到同一个实例上,就是实例上。
08:27
不会存在数据不一致的问题。就是可能,嗯,对,可能存在这种数据不一致的问题,就是我们在主层同步的时候,对吧,最后一点就是性能啊,Red比Su keepper肯定性能要高,因为我们内存为内存,对比这个磁盘,嗯,明显显而易见的。所以还是我们说的系统设计,具体问题具体分析,或什么时候用red,什么时候用K本,就要看我们这个系统的场景嘛,对吧?如果我们是强意识的分布式系统,我们就需要做K本,嗯,那么以上就是这个分布式锁如何实现的全部内容了,嗯,觉得不错的话记得点赞支持一下,谢谢。
我来说两句