史上最全面的关于大数据的分布式锁(六) 不会真的有人白嫖吧

什么是锁?

  • 在单进程的系统中,当存在多个可以同时改变某个变量时(可共享变量),就需要对变量或者代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量
  • 而同步的本质是通过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都看到,当标记不存在是可以设置该标记,其余后续线程发现已经有标记了则进行等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记。这个标记可以理解为锁。
  • 不同的地方实现锁的方式也不一样,只要能够满足所有线程都能看到标记即可。如Java中synchronize是在对象头设置标记,Lock接口的实现类基本上都是只是某一个volititle修饰的int型变量其保证每个线程都能拥有对该int的可见性和原子修改,LINUX内核中也是利用互斥量或者信号量等内存数据做标记。
  • 除了利用内存数据做锁其实任何互斥都能做锁(只考虑互斥情况),如流水中流水号于时间结合做幂等校验可以看做是一个不会释放的锁,或者使用某个文件是否存在作为锁等,只要满足在对标记进行修改能保证原子性能和内存可见性即可。

什么是分布式

分布式的CAP理论:

任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Avaliability)和分区容错性(Partititon tolerance),最多只能满足两项。

目前很多大型网站及引用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。基于CAP理论,很多系统在设计之初就要对这三者做出取舍。在互联网领域的绝大多数的场景中,都需要牺牲一致性来换取系统的高可用性,系统往往只需要保证最终一致性。

什么是分布式锁?

在很多应用场景下 ,为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务,分布式锁等。很多时候我们需要保证一个方法在同一个时间内只能被同一个线程执行。在单机环境中,通过Java提供的并发API我们可以解决,但是在分布式环境下,可能就没有那么简单了。

  • 分布式与单机环境下最大的不同在于其不是多线程而是多进程
  • 多线程由于可以共享堆内存,因此可以简单的采取内存作为标记存储位置,而进程之间甚至可能都不在同一台物理机上,因此需要将标记存储在一个所有进程都能看到的地方。
  • 在分布式模型下,数据只有一份(或有限制),此时需要利用锁的技术控制某一时刻次改数据的进程数。
  • 与单机模式的锁不仅需要保证进程可见,还需要考虑进程与锁之间的网络问题
  • 分布式锁还是可以将标记存在内存,只是该内存不是在某个进程分配的内存,而是公共内存,例如Redis,Memcache。甚至利用数据库、文件等锁与单机实现是一样的,只要保证标记能够互斥就行。

分布式锁应该是什么样的?

  • 可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上一个线程执行。
  • 这把锁要是一把可重入锁(避免死锁)
  • 这把锁最好是一把阻塞锁(根据业务场景)
  • 最好是一把公平锁(根据业务场景)
  • 有高可用的获取和释放锁的功能
  • 获取锁和释放锁的性能要好

分布式锁的实现方式

  • 数据库
  • Redis
  • Zookeeper

猜你喜欢

转载自blog.csdn.net/artiil/article/details/107122841