【Redis】redis分布式锁(一)

我的个人博客:https://www.wuyizuokan.com

介绍

在以前,服务基本上都是处于一个进程中,在同一进程中的不同线程要访问和操作同一个资源,可以使用编程语言提供的同步锁机制;但现在那些庞大的服务都已经被服务化和分布式化了,这样需要操作一个资源的可能就是一个个服务进程了,因为是进程和进程的关系,进程之间的编程语言也有可能不一样,导致之前在同一进程中可以使用的同步锁机制就失效了。

 

如果这个共享在服务间的资源提供的所有操作都是原子操作,而且各个服务也不会进行原子操作的组合使用(当然这是不可能的),那其实要不要锁资源都无所谓,毕竟所有操作都是原子性的。这里要说这个原子操作的组合使用,为何会出现问题呢?其实显而易见,在两个原子操作之间,如果没有锁机制,就有可能别的服务插入进来,导致资源出现不一致。

这里又要解释一下什么是原子操作?其实就是从一个操作执行开始,到这个操作执行结束,都不会出现第三者插入进来执行别的操作的情况。

比如x+1这个操作是否是原子性的呢?可以说是的,它的确是原子性的因为它只有一步,别人没办法插入进来;

但是如果是x=x+1呢?这个就不是原子性的了,x=x+1中包含了两步操作:一个是x+1,一个是把x+1的结果赋值给x,两部操作,中间就容易有人插入。

 所以要保证原子性,可以从两点入手,其一就是保证你的操作只有一步(很不现实);其二,保证你在进行多步操作期间,不会有人插足。

所以才会出现锁这种东西,将自己要进行操作的资源锁定起来,其他人想来操作都会失败,这样就能保证操作的原子性。

以前可以使用编程语言提供的线程间的锁机制,但现在是进程和进程间存在抢占资源的情况,就必须要有进程和进程之间的锁机制了,这个就是分布式锁。

而Redis可以提供这种分布式锁的能力。当然除了Redis外,还有其他的三方件可以提供这种能力,比如zookeeper。

在Redis中,可以使用setnx命令和del命令来获取锁和释放锁。

set name value命令是创建一个string的键值对,而setnx name value是如果name不存在,则创建这个键值对,否则不创建。通过这个命令,相当于多个服务去抢着创建自己的锁,先到先得,后到的就只能等了。而使用del 命令删除掉这个锁之后,其他服务就可以再次尝试创建自己的锁。

演示

下面准备使用三个服务来进行演示,其中一个服务提供一个资源增删改查的接口,另外两个服务来调用这些接口操作资源,同时通过使用Redis分布式锁机制,来保证操作的原子性。

 第一个服务是提供了资源操作接口的服务,服务的创建可以参考这篇博文,使用SpringBoot快速搭建一个微服务,并提供restful风格的接口:

https://www.cnblogs.com/wuyizuokan/p/11117294.html

 第二个服务是使用Go语言开发的,可以调用上面的服务的Rest接口查询和修改计数:

https://www.cnblogs.com/wuyizuokan/p/11160790.html

第三个服务是使用python语言开发的,可以调用上面的服务的Rest接口查询和修改计数:

https://www.cnblogs.com/wuyizuokan/p/11185214.html

 

posted @ 2019-06-30 21:30  微弦  阅读(234)  评论(0编辑  收藏  举报