项目中用到了Redis分布式锁,了解一下背后的原理

前言

之前在学校作小项目的时候,用到Redis,基本也只是用来看成缓存。如今博主在某金融平台实习,发现Redis在生产中并不仅是看成缓存这么简单。在我接触到的项目中,Redis起到了一个分布式锁的做用,具体状况是这样的:redis

该项目在金融平台中负责某块业务,是一个分布式系统,线上大概跑着10个左右的实例。其中有一个步骤须要用户支付必定的费用,Redis分布式锁在其中大概处于这么一个位置:算法

能够看到在上分布式锁以后,系统作了两个查询校验,而后向数据库中插入了一条订单记录,接着才解锁进入支付流程。数据库

从业务的角度考虑分布式锁是好理解的,它保证了查询及插入数据整个流程的原子性,防止查询校验的时候查到脏数据,使得支付前订单信息落表的操做串行化执行。缓存

尽管从业务上来讲很好理解,但使用Redis做为分布式锁对我来讲是个新知识,我打算结合项目中的代码,深挖一下这个知识点。安全

正文

1. 为何要使用分布式锁

在实际项目中见过度布式锁后,就不难理解为何要使用分布式锁了:总结来讲就是分布式系统要访问共享资源,为了不并发访问资源带来错误,咱们为共享资源添加一把锁,让各个访问互斥,保证并发访问的安全性,这就是使用分布式锁的缘由。并发

2. Redis中分布式锁的实现

redis中使用分布式锁很简单,只要使用setnx指令对某个key上锁就行:分布式

setnx lock test //上锁
del lock test   //解锁

当某个key没有被占用的时候,setnx指令会返回1,不然返回0,这就是Redis中分布式锁的使用原理。性能

固然咱们还能够在上锁以后使用expire指令给锁设置过时时间。学习

看到这里你可能会有疑问,若是咱们的程序流程不使用指令解锁,靠redis设置时间过时来解锁,貌似会出问题。假如咱们的服务进程在执行setnx以后和执行expire指令以前挂掉了,那这个锁岂不是永远都不能被释放?code

没错,这确实是个问题,当时人们在Redis的开源社区提出了一堆解决方案专门来解决这个问题,可实现方式都极为复杂。后来Redis的做者在Redis 2.8版本中加入了set指令的扩展参数,使得setnx指令和expire指令可以同时执行,具体使用像下面这个样子:

set lock test ex 5 nx
ex:设置键的过时时间
nx:只在键不存在时,才对键进行设置操做

今后之后,Redis成为了分布式锁的宠儿。

3. 分布式锁在Redis集群中遇到的麻烦

在学习了Redis中分布式锁的使用后,很快咱们便发现了新的问题。在企业中,Redis基本上都是集群部署的,集群部署避免不了要面对某个节点宕机的问题。

咱们考虑这么一种状况:假设咱们在redis的主节点上添加了一把分布式锁,不幸的是主节点挂掉了,并且主节点上的锁尚未同步到从节点上,若是此时有客户端来请求得到同一把锁,那么它将顺利地得到锁,以前那把锁会被无情地忽视掉,这就是分布式锁在Redis集群中遇到的麻烦。

Redis的做者为了解决这个问题提出了一个叫Redlock的算法,它的原理是这样的:当上锁的时候,把set指令发送给过半的节点,只要过半的锁set成功,就认为此次加锁成功;当解锁的时候,会向全部的节点发送del指令。

从这个算法的原理能够看出,因为Redlock须要同时对多个节点进行读写,所以使用Redlock加分布式锁的性能要比单机Redis低不少。由于主从复制出纰漏的几率极低,因此若是对分布式加锁过程有必定的容错率的话,能够考虑直接使用set指令;若是追求高可用性,能够考虑使用Redlock算法。

固然,高可用性的分布式锁不仅有Redis的Redlock,咱们还能够用zookeeper或者支持事务的数据库作分布式锁。

简述zookeeper的分布式锁原理:假设zk用某个节点做为分布式锁,当不一样的客户端到zk竞争这把锁的时候,zk会按顺序给不一样的客户端建立一个子节点,挂在做为分布式锁的节点下面。假设第一个来到的客户端为A,第二个来到的是B,分布式节点下挂的第一个节点就是A,B紧跟着A,且B会监听着A的生命状态,当A释放锁后A会被删除,这时B监听到A被删除,B接能上位得到分布式锁了。

在公司的项目中,虽然Redis是以集群的方式部署的,但仍是使用最基本的set指令获取分布式锁,由于这种方式的性能远远高于Redlock算法,也高于zk,数据库等分布式锁实现方式。

虽然在高性能与低几率的错误中选择了高性能,但项目中仍是作了其余工做对错误状况进行兜底的,好比在公司的项目中对主从复制时的错误状况会抛出异常,而后根据异常会进行一些重试的操做。

总结

此次对Redis分布式锁的探索算是加深了本身对Redis的理解,但我知道Redis的用处还远远不止分布式锁和缓存,留着后面继续探索吧。

相关文章
相关标签/搜索