码迷,mamicode.com
首页 > 其他好文 > 详细

分布式&分布式锁&Redis分布式锁

时间:2019-02-08 23:17:53      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:可重入锁   partition   无法   过期   避免死锁   高可用性   场景   网络   开启   

一、什么是分布式
分布式的CAP理论告诉我们:任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。
C:一致性,在分布式环境下,一致性是指多个节点同一时刻要有同样的值;
A:可用性,服务一直保持可用状态,当用户发出一个请求,服务能在一定时间内返回结果;
P:分区容忍性,即使单个组件不可用,操作依然可以完成;
目前很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。基于CAP理论,很多系统在设计之初就要对这三者进行取舍。在互联网领域绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证最终一致性。
(分布式场景:此处主要指集群模式下,多个服务同时开启)
在许多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如“分布式事务”、“分布式锁”等。很多时候我们需要保证一个方法在同一时间内只能被同一个线程执行。在单机环境中,通过Java提供的并发API即可解决,但是在分布式环境下,就没有那么简单了:
1.分布式与单机情况最大的不同在于其不是多线程而是多进程;
2.多线程由于可以共享堆内存,因此可以简单地采取内存作为标记存储位置;而进程之间甚至可能都不在同一台物理机上,因此需要将标记存储在一个所有进程都能看到的地方。

二、什么是分布式锁
1.当在分布式模型下,数据只有一份(或有限制),此时需要利用锁的技术控制某一时刻修改数据的进程数;
2.与单机模式下的锁相比,分布式锁不仅要保证各种特性,还需要考虑进程与锁之间的网络问题(网络延时与可靠性);
3.分布式锁还是可以将标记存在内存,不过该内存不是某个进程分配的内存,而是公共内存如Redis、Memcached,至于利用数据库、文件等做锁与单机的实现是一样的,只要能保证标记互斥就可以。

分布式锁的主要使用场景:比如生成ID;线程A和线程B都共享某个变量X。如果是单机情况下(单JVM),线程之间共享内存,只要使用线程锁就可以解决并发问题。如果是分布式情况下(多JVM),线程A和线程B很可能不是在同一JVM中,这样线程锁就无法起到作用了,这时候就要用到分布式锁来解决。

三、我们需要怎样的分布式锁
1.可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行;
2.这把锁需要是一把可重入锁(避免死锁)
3.这把锁最好是一把阻塞锁(根据业务需求考虑要不要加这条)
4.这把锁最好是一把公平锁(根据业务需求考虑要不要加这条)
5.有高可用的获取锁和释放锁功能

四、基于数据库做分布式锁

五、基于ZooKeeper做分布式锁

六、基于Redis做分布式锁(性能最棒)
1.Redis的基本命令:
SETNX key value
如果key不存在,就设置key对应字符串value。在这种情况下,该命令和SET一样。当key已经存在时,就不做任何操作。SETNX是”SET if Not eXists”。
expire KEY seconds
设置key的过期时间。如果key已过期,将会被自动删除。
del KEY
删除key

2.需要考虑的问题
(1)用什么操作Redis?
幸亏Redis已经提供了Jedis客户端用于Java应用程序,直接调用Jedis API即可。
(2)怎么实现加锁?
“锁”其实是一个抽象的概念,将这个抽象概念变为具体的东西,就是一个存储在Redis里的key-value对,key是于商品ID相关的字符串来唯一标识,value其实并不重要,因为只要这个唯一的key-value存在,就表示这个商品已经上锁。
(3)如何释放锁?
既然key-value对存在就表示上锁,那么释放锁就自然是在Redis里删除key-value对。
(4)阻塞还是非阻塞?
笔者采用了阻塞式的实现,若线程发现已经上锁,会在特定时间内轮询锁。
(5)如何处理异常情况?
比如一个线程把一个商品上了锁,但是由于各种原因,没有完成操作(在上面的业务场景里就是没有将库存-1写入数据库),自然没有释放锁,这个情况笔者加入了锁超时机制,利用Redis的expire命令为key设置超时时长,过了超时时间Redis就会将这个key自动删除,即强制释放锁(可以认为超时释放锁是一个异步操作,由Redis完成,应用程序只需要根据系统特点设置超时时间即可)。

分布式&分布式锁&Redis分布式锁

标签:可重入锁   partition   无法   过期   避免死锁   高可用性   场景   网络   开启   

原文地址:https://www.cnblogs.com/yuanfei1110111/p/10356805.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!