分布式系统不可能同时满足一致性,可用性和分区容忍性,最多只能同时满足其中的二项。
其中,网络分区指的是分布式系统中的节点被划分为多个区域,每个区域内部可以通信,但是区域之间无法通信。在分区容忍性条件下,分布式系统在遇到任何网络分区故障时,仍然需要对外提供一致性和可用性服务,除非整个网络环境发生了故障。
另外,可用性和一致性往往是冲突的。
- 为了保证一致性,需要让所有的节点下线成为不可用状态,等待同步完成。
- 为了保证可用性,在同步过程中允许读取所有节点的数据,但是数据可能不一致。
BASE
BASE是基本可用(Basically Available),软状态(Soft State),最终一致性(Eventually Consistent)这3个短语的缩写。
BASE理论是对CAP中的一致性和可用性权衡的结果。它的核心思想是:即使无法做到强一致性,但是每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终的一致性。
- 基本可用(Basically Available) 基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。 电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
- 软状态( Soft State) 软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql
replication的异步复制也是一种体现。 - 最终一致性( Eventual Consistency) 最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
2PC(两阶段提交)
- 准备阶段:协调者询问参与者事务是否执行成功,参与者发回事务执行结果。
- 提交阶段:如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。
分布式锁
在分布式系统中,由于分布式系统的分布性,即多线程和多进程分布在不同的机器中,ReentrantLcok和Synchronized这两种锁将失去原有锁的效果,需要我们自己实现分布式锁——分布式锁。
分布式锁需要具备的条件:
- 获取锁和释放锁的性能要好
- 判断是否获得锁必须是原子性的,否则可能导致多个请求都获取到锁。
- 网络中断或宕机无法释放锁的时候,锁必须被清除,不然会发生死锁。
- 可重入一个线程中可以多次获取同一把锁,比如一个线程在执行一个带锁的方法,该方法中又调用到了另一个需要相同锁的方法,则该线程可以直接执行调用的方法,而无需重新获取锁。
- 阻塞锁和非阻塞锁,阻塞锁没有获取到锁,则继续等待获取锁;非阻塞锁即没有获取到锁后,不继续等待,直接返回锁失败。
分布式锁的实现
-
数据库锁
该实现方式完全依靠数据库唯一索引来实现,当想要获取锁的时候,即向数据库插入一条记录记录,释放锁的时候删除这条记录。
Problem:
锁没有失效时间,解锁失败会导致死锁。
只能是非阻塞锁,insert失败会直接报错,无法进入队列重试
不可重入,同一线程在没有释放锁之前无法在获取到锁 -
缓存锁
基于redis实现的分布式锁
RedLock算法
1 获取当前时间
2 尝试从5个相互独立的redis客户端获取锁
3计算获取所有锁消耗的时间,当且仅当客户端从多数节点获取锁,并且获取锁的时间小于锁的有效时间,认为获得锁。
4 重新计算有效期时间,原有效时间减去获取锁消耗的时间。
5 删除所有实例的锁。