当前位置:首页 > 技术文章 > 正文内容

终于搞懂分布式锁是什么了

arlanguage4个月前 (01-06)技术文章36

当下在互联网技术架构中,最流行的莫过于分布式架构了。为什么大家纷纷都采用分布式架构呢?


1、高效低廉,将部署在高性能机的程序分散在多个小型机中部署;

2、扩展性强,可随着业务的扩展而横向扩展系统的性能;

3、可靠性强,当系统中一台或几台出现故障时,仍然有其它机器在提供服务;

4、并发性强,各台机器同时运作提供服务。


分布式,真香!


不过使用分布式架构也会存在一些问题最严重的问题便是数据一致性问题。因为业务是部署在多台机器上,由于时间空间的不一致,从而导致数据会不一样,分布式的CAP理论已经告诉我们“分布式系统无法同时满足一致性Consistency、可用性Availability、分区容错性Partitiontolerance,最多满足两项”。对于数据不一致的问题,互联网有几种思考,比如BASE服务基本可用,牺牲暂时的数据不一致,只要数据最终一致即可;采用分布式事务进行解决;采用分布式锁进行解决。而今天我们要介绍的便是分布式锁的解决方案。


首先来看一个具体的case解释为什么需要分布式锁。在电商业务采用分布式架构后,程序部署在3个tomcat容器中(1个tomcat容器代表一个服务器,3个tomcat可理解在北京上海深圳都有部署电商服务),成员变量A代表商品数量。在北京的Alice,上海的Bob,深圳的Tom,都分别发起了购买或取消iPhone12的用户请求,经过Nginx负载均衡将Alice的请求发给了北京服务器,Bob的请求发给了上海服务器,Tom的请求发给了深圳服务器,这时候每台服务器都会对iPhone12这个商品数量进行更改,Alice的请求是将商品数量加到200,Bob的请求是将商品数量减少100,Tom的请求是将商品数量加1,如果对于商品数量的修改没有任何限制,整体就会乱起来,可能Bob的先减少,Tom的在增加,数据就完全乱了,所以需要分布式锁解决方案。



锁的概念并不是在分布式中才存在,传统互联网的开发中也存在锁。比如在多进程处理请求时,内存资源就会不足,这时候操作系统会使用信号量来解决资源的抢夺,如果信号量的值大于0,则将信号量数值减1,同时分配内存资源,如果信号量的值小于0,则进程处于等待状态,其他进程操作执行完毕后,信号量数值加1,唤醒等待的进程。


总结一下,实现锁有三个要素

1、有存储锁的空间,在多进程中,内存就是存储锁的空间,通过对锁的控制实现不同进程的访问控制。2、能唯一标识,不同的空间用不同的锁保护,那必须要唯一标识。
3、有状态,即存在、不存在。在分布式系统环境中,分布式锁就是一个变量一个方法在同一时间只能被一个机器的一个线程执行,对分布式锁的实现也提出了更高的要求,即需要高性能高可用的获取与释放锁,需要锁超时机制,避免死锁出现。


那么如何实现分布式锁呢?业内有三种实现方式:

1、基于数据库;

2、基于redis;

3、基于Zookeeper。


对于第一种实现方案,很简单,我们知道在传统数据库中是有ACID事务原子性、一致性、持久性、可用性规则的,如果基于数据库实现分布式锁,只需要在数据库中创建一个表,表中包含方法名,对方法名加上唯一索引,想要执行该方法时,就使用这个方法名向表中插入数据,插入时,其它数据都没法插入,等于获得锁,成功插入后,删除对应的数据释放锁。这种方案的好处就是简单,但存在的问题是对数据库要求高,因为数据库的可用性、性能会直接影响分布式锁的可用性,数据库可能需要主从部署、读写分离。


对于第二种实现方案,只需要使用redis的命令setnx、expire、delete就可以了(请允许我再感叹一下,redis真的太好用了,又简单性能又好),setnxkeyvalue就会给某个变量赋予一个值,返回1,当业务请求来时,如返回key值为1,线程获得锁,如果key值为0,线程抢锁失败。


对于第三种实现方案,我们知道zookeeper是一个分布式协调服务,它内部是一个分层的文件系统目录树结构,同一个目录下只能有一个唯一文件名,因此当实现分布式锁时,只需要创建一个目录,线程想要获取锁就在目录下创建临时顺序节点,然后遍历获取是否存在比自己小的节点,如果存在则获取锁失败,如果不存在则获取锁成功,缺点就是会频繁的创建节点。


通过本文的介绍,认真阅读的小伙伴又获得了分布式架构使用的一个技巧。在分布式环境中,对资源的上锁非常重要,通过分布式锁解决了数据的一致性问题,小伙伴们可以根据自己业务实际情况选择合适的分布式锁方案噢~

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/641.html

分享给朋友:

“终于搞懂分布式锁是什么了” 的相关文章

【Nginx进阶】Nginx安全配置

在本章中,我们将详细介绍 Nginx 的安全配置,包括 SSL/TLS 安全、访问控制、HTTP 安全头、防止 DDoS 攻击和日志审计。Nginx安全配置在现代网络环境中,保障 Web 服务器的安全性至关重要。Nginx 作为一个高性能的 Web 服务器和反向代理服务器,通过合理的安全配置,可以有...

Nginx热升级流程,看这篇就够了

在之前做过 Nginx 热升级的演示,他能保证nginx在不停止服务的情况下更换他的 binary 文件,这个功能非常有用,但我们在执行 Nginx 的 binary 文件升级过程中,还是会遇到很多问题,比如老的 worker 进程一直退不掉或者新的 worker 进程升级以后出现问题需要考虑回滚,...

常见nginx配置文件的主上下文指令有哪些?

Nginx 由模块组成,这些模块由配置文件中指定的指令(directive)来控制。指令被分为简单指令和块指令。简单指令由名称和用空格分隔的参数组成,并以分号 (;) 结尾。块指令与简单指令具有相同的结构,但是在分号的位置,它以一组用大括号 ({ 和 }) 括起来的额外指令结束。如果块指令可以在大括...

Java学习路线总结

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象、数组、集合、IO流、String/StringBuffer/StringBuilder、线程、并发、反射、...

nginx反向代理配置去除前缀

使用Nginx做代理的时候,可以简单的直接把请求原封不动的转发给下一个服务。比如,访问abc.com/appv2/a/b.html, 要求转发到localhost:8088/appv2/a/b.html简单配置如下:upstream one { server localhost:8088 wei...

Nginx 转发时的一个坑,运维居然让我背锅

最近遇到一个 Nginx 转发的坑,一个请求转发到 Tomcat 时发现有几个 http header 始终获取不到,导致线上出现 bug,运维说不是他的问题,这个锅我背了。新增的几个 header 是这样的:accept_signaccept_token…反复检查代码,确定这些 header 是传...