分布式锁

如果不用分布式锁,有哪些问题?

现在的架构基本都是先分布式再集群化:

比如,有库存服务集群,下单服务集群等等。

一个集群中的所有服务器,干的事都是一样的,用户的请求会被分散到集群中的某些服务器上,

 

最主要的问题就是数据库压力太大

当这些服务器对一些共享资源做读写请求的时候,就可能会出问题。

为什么说是可能,因为我们可以通过优化sql的写法,写带锁的sql语句,以及限定某些字段不能为负值等方法,去解决问题,但是带来的问题就是数据库的压力炒鸡大,炒鸡大! 

其次的是数据共享问题

为什么是其次,因为,即使是单机,不加互斥锁,多线程下环境下,如果业务逻辑上有错误,也会导致问题,比如并发的减库存

java代码是这么写的

int num = dao(select num from goods where goods_id  = 1;)

int num = num - 100;

dao(update set num = #{num} where goods_id =1;)

并发情况下,就有可能出问题了,假设两个请求并发执行,原来800 并发减完 有可能只是是700

但是这种错误,我感觉在开发阶段就不会出现这样的错误,所以我认为,如果不加锁最大的问题就是数据库压力太大的问题

分布式锁有什么用?

1:把锁的环节提前了,降低了数据库的压力:

如果真的是所有请求都去修改数据库中的同一个字段,即使到了数据库层面也是串行化写,因为数据库通过互斥锁,

保证了同一时刻只能有一个事务在修改同一数据,但是我们的访问请求却都到达了数据库,这样给数据库带来的压力炒鸡大!!!

2:比如现在有1000个商品,分布式锁做到了针对同一商品的集群级别的串行化写

我们通过一个集群级别的互斥锁,让同一时刻只能有一个请求去数据库中修改同一商品

我们不用在service层加同步锁,因为不同的请求的请求的可能不是同一个商品!!!

实现的方式

1:redis分布式锁

对一个商品加锁,就是在redis里set一个key是goods_id,value是对应这个请求的唯一的值 的数据,解锁的时候把该数据删掉就行了

1:set goods_id  unique_value  NX PX 30000(加锁和设置过期时间  必须放在一条指令里,保证是操作原子的)

       goods_id 表示锁的对象

      unique_value 用来区别请求,防止其它请求去解锁不是他创建的锁

      

      NX表示 key不存在的时候这条语句才有用,PX表示过期时间的单位是 毫秒 30000 表示30000毫秒

2:解锁

     redis保证执行lua脚本是原子的,解锁可以用lua脚本

//判断 redis 中 goods_id 对应的 unique_value 是否等于客户端传进来的value
if redis.call("get","goods_id") == "value" then	
   return redis.call("del",KEYS[1])	
else	
   return 0	

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值