CAP理论:
Consistency,一致性:多个操作同时生效,不会出现部分生效的情况
Availability,可用性:客户端的每个请求在服务端能够正确被响应
Partition tolerance,分区容错性:分区中部分节点挂了不会影响整体服务可用性
分区容错性是一个分布式系统最基本的要求,因此一般分布式系统都会满足分区容错性
分布式系统一般会在C(一致性)和A(可用性)上做出取舍
例:
server-01 (update i = 1) => server-02 通信网络故障时,user请求获取server-02 的i ,由于数据未同步,什么办呢?
1、牺牲一致性,响应旧的i 给user
2、牺牲可用性,阻塞等待 直到网络回复,数据更新完,在响应给user
AP:放弃了强一致性
CP:放弃了可用性,影响用户体验。
一般情况下,都需要牺牲强一致性来换取系统的高可用性。
牺牲掉系统的'强一致性',最终是一致的,既'弱一致性'或'最终一致性',服务延迟或down机整个系统不可用,也是强一致性的表现。
为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等
分布式锁一般有三种实现方式:
一、数据库锁
数据库中创建一个method_lock表 method_name做唯一约束,然后通过操作该表中的数据来实现了
要锁住某个方法或资源时,我们就在该表中增加一条记录,想要释放锁的时候就删除这条记录
基于数据库锁的缺点:
1.1、基于数据库 影响可用性和性能,需要双机部署 数据同步 主备切换,同时依赖数据库一些资源开销等
1.2、不可重入
1.3、没有锁失效机制:如 insert成功 down机了 对应数据没有删除,服务恢复后一致获取不到锁
1.4、不具备阻塞锁特性
二、Redis的分布式锁
基于缓存来实现、可以集群部署
使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间自动释放锁
三、基于ZooKeeper的分布式锁
基于zookeeper临时有序节点可以实现的分布式锁 (对应的方法临时有序结点)
每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。
判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。
当释放锁的时候,只需将这个瞬时节点删除即可。
同时,可以避免服务宕机导致的锁无法释放,而产生的死锁问题。
具备高可用、可重入、阻塞锁特性、可解决失效死锁问题,因为需要频繁的创建和删除节点,性能上不如Redis方式
相对于CAP理论:BASE是对CAP中一致性和可用性权衡的结果
BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)