CAP理论
的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性), 三者不可得兼
- 一致性(C):在分布式系统中,所有节点对外看起来像是同一个数据副本 —— 读取到的都是最新的同一份数据。
- 可用性(A):只要客户端发起请求,系统就必须持续给出响应(不挂、不超时),无论数据是否是最新的。
- 分区容忍性(P): 系统即使部分节点之间的网络断了,也能继续对外提供服务。
redis实现分布式锁
分布式锁是用于分布式环境下并发控制的一种机制,用于控制某个资源在同一时刻只能被一个应用所使用。Redis 本身可以被多个客户端共享访问,正好就是一个共享存储系统
Redis的 SET 命令有个 NX 参数可以实现「只在锁的key键不存在时才设置」,所以可以用它来实现分布式锁:
- 加锁包含三个条件(读取锁变量,检查锁变量,设置锁变量值)
- 解锁包含两个操作(判断当前锁是不是自己客户端设置的,释放)
NX参数确保了加锁的原子性,为了确保解锁操作的原子性,需要使用lua脚本
通过 Lua 脚本,把一系列 Redis 命令打包成一个原子操作在服务端一次性执行,避免多次网络往返,也避免并发冲突。
分布式事务
多个系统或多个数据库之间的操作,要么全部成功、要么全部失败,就像一笔原子事务一样。然而分布式事务难于统一管理提交/回滚 —— 这就是 分布式事务问题。
解决方案
- 2PC:准备和提交两阶段
- 3PC:准备阶段拆分为询问和准备,提交
- TCC:将业务操作拆分为 Try、Confirm、Cancel 三个阶段
- 消息队列:业务系统执行本地事务时将业务操作封装成消息发至消息队列,下游系统消费消息并执行操作,失败则消息队列重试。
- 本地消息表:业务与消息存储在同一个数据库,利用本地事务保证一致性,后台任务轮询消息表,通过MQ通知下游服务,下游服务消费成功后确认消息,失败则重试。
- saga:将长事务拆分为多个短事务,每个短事务有对应的补偿事务。
分布式一致性算法
Raft算法由leader节点来处理一致性问题。
- Leader 选举:一个节点成为 Leader,其它是 Follower
- 日志复制:客户端请求发送给 Leader,由它把操作同步到多数 Follower
- 一致性提交:一旦多数节点写入成功,Leader 提交操作,并通知其他节点
paxos将一致性问题分解为多个阶段,每个阶段都有一个专门的协议来处理。
- 提议者:提议者是负责提出一致性问题的节点,它会向接受者发送提议,并等待接受者的回复。
- 接受者:接受者是负责处理提议的节点,它会接收提议者发送的提议,并对提议进行判断。如果接受者认为提议是有效的,它会向投票者发送请求,并等待投票者的回复。
- 投票者:投票者是负责决定提议是否有效的节点,它会接收接受者发送的请求,并对请求进行判断。如果投票者认为请求是有效的,它会向接受者发送投票,表示支持或反对提议。
RPC(分布式组件)
RPC 即远程过程调用协议,允许程序调用运行在另一台计算机上的程序中的过程或函数,就像调用本地程序中的过程或函数一样,而无需了解底层网络细节。一种高效的应用程序之间的通讯手段
常见的RPC框架:
- Dubbo:Dubbo是一个分布式服务框架,以及SOA治理方案。
- Thrift
- GRPC:由 google 开发,基于HTTP/2协议标准而设计,基于ProtoBuf序列化协议开发,且支持众多开发语言。
- Spring Cloud
一个典型的 RPC 调用过程通常包含以下几个步骤:
- 客户端调用:客户端程序调用本地的一个 “伪函数”(也称为存根,Stub),并传入所需的参数。这个 “伪函数” 看起来和普通的本地函数一样,但实际上它会负责处理远程调用的相关事宜。
- 请求发送:客户端存根将调用信息(包括函数名、参数等)进行序列化,然后通过网络将请求发送到服务器端。
- 服务器接收与处理:服务器端接收到请求后,将请求信息进行反序列化,然后找到对应的函数并执行。
- 结果返回:服务器端将函数的执行结果进行序列化,通过网络发送回客户端。
- 客户端接收结果:客户端接收到服务器返回的结果后,将其反序列化,并将结果返回给调用者。
RPC主要完成的步骤时2-8
然而,当客户端调用多个远程函数的时候,涉及到大量的请求和多个服务器(机器、提供方),就需要产生相应的网关路由层,根据不同服务器的IP地址去进行调用,这就涉及到服务注册和服务发现
- 服务注册:服务器向服务中心注册自己信息(ip地址、端口等)的过程
- 服务发现:客户端通过注册中心查询所需服务器网络位置的过程