这是我参与「第五届青训营 」笔记创作活动的第1天
分布式概述
定义
人们希望在单个节点受限的情况下,把功能分配到多个节点共同实现
优势
- 去中心化:把一个大型服务器分成一个个小的服务器组成的集群,增强了存储和运算能力
- 低成本:一台大服务器的价钱可以买很多小服务器,相同价钱做更多事
- 弹性:服务面向用户,用户访问有波峰波谷,分布式可以根据用户访问弹性分配资源,如白天在线服务,夜里离线计算,促销服务扩容等
- 资源共享:单台服务器存储资源有限,分布式把服务器存储资源集中,更大发挥效能
- 可靠性高:分布式采用多副本冗余保证系统可靠性,比如一个节点硬盘坏了,可以用另一个节点的副本
挑战
- 节点故障很常见
- 网络稳定性差,大型数据中心网络故障要当成常态
- 异构的机器和环境:程序性能不可预测,某程序在集群中A机器的环境性能好,当被调度到B机器的环境其性能不可预测
- 安全:集群节点被攻破整个集群数据都有风险
why-how-what看待分布式理论
- 为什么使用分布式
- 怎么用好分布式
- 做些什么
常见分布式系统
- GFS:分布式系统开山鼻祖
系统模型
故障模型
分布式系统不得不面对故障,根据对故障处理的难易程度划分六种故障
- byzantine failure:广义故障,最难处理,通常发生在网络出现严重问题时
- ADB:身份可检测的拜占庭故障,磁盘发生错误可能发生
- performance:处理慢了
- omission failure:节点收到数据无限晚
- crash failure:如宕机,进程退出
- fail-stop failure:可以知道错误码,既错误原因
故障模型的四个维度
- 正确性
- 时间
- 状态
- 原因
依据4个维度分析六种故障
- fail-stop failure:知道故障原因
- crash failure:只知道故障状态,不知道故障原因
- omission failure:未决状态,长时间未决,但是可以确定是故障
- performance failure:未决状态,不能知道是否是故障
- byzantine failure:正确性问题,不知道消息是真还是伪,大多数分布式系统不处理byzantine failure,实际工作中一般做加密和冗余来避免byzantine failure
故障现场对应模型
拜占庭将军问题-通信问题
- 问题背景:拜占庭帝国有两只军队要和敌方打仗,任和一支军队单独作战都会失败,因此他们有两种选择,要么不打,要打就只能同时进攻。因此进攻的时间要达成共识(两方进攻时间即进攻行动达成一致,不能一方动一方不动)
- 结论:两支军队理论上完全无法保证达成共识,即无法达成共识
- 分析:A给B发送进攻消息,A不能保证B收到进攻消息,假如A在假设发送进攻消息B一定收到的情况下,B没有收到消息,则A动B不动,共识失败;现进一步假设AB有如下约定:A发送消息,B恢复确认消息,则有可能B收到进攻消息且发送确认消息,A未收到确认,B动A不动情况,共识失败;若再加一条确认则会再加一层猜疑链,因此永远无法达成共识
- 解法:一般来说增加超时重试机制(方案2)
更普适的拜占庭将军问题-三将军问题
三将军互相传递消息,当出现一个叛徒将军(即拜占庭故障)时,系统将无法达成一致
- 解决:增加一个中枢将军
共识和一致性
- 线性一致性:版本递增,不会发生回退,要实现线性一致性客户端之间要进行同步,会增加延迟,系统可用性受损
时间和事件顺序
时间和事件顺序构建了分布式的大厦,如分析看似无关的事件的关系p1与r4,可以通过p1->q2->q4->r3->r4推导而来
lamport逻辑时钟
时间和事件顺序用来给事件定性,则逻辑时钟用来定量,Lamport认为一切分布式事件都可以映射为逻辑时钟的值,利用lamport逻辑时钟能为每个分布式事务定义一个时间戳,更好了解和解决分布式事务的隔离性问题
理论基础
CAP理论
- CAP理论矛盾:一个系统永远无法达到CAP,可以无限逼近
- 网络分区:在分布式环境下,有时由于网络通讯故障,而不是服务器上的应用故障,导致一些节点认为应用不可用,另外一些节点认为应用仍可用。导致,整个系统在提供服务时,造成了不一致性。
强调可用性A
强调一致性C
做一定的取舍
一致性和可用性都会损失,但是做到了均衡
ACID理论
面向CA系统,如传统数据库
事务
事务是数据库的基本处理单元
事务特性(ACID)
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
一个合格的数据库一定要保证A和C
ACID的C和CAP的C
ACID的C是事务的一致性,如一次转账操作账户总和总是不变的,CAP的C是线性一致性,其对象是节点和进程,数据在节点间通信,在任何时候看见的都是一样的状态
BASE理论
面向AP系统
- B:Basically Available(基本可用),AP系统的核心
- S:Soft state(软状态)
- E:Eventually consistent(最终一致性)
分布式事务
二阶段提交
一个正常的流程-以A向B转账2w为例:
- 一阶段:协调者(coordinator)向参与者(participant)发出prepare指令,收到指令后,participantA执行-2w,participantB执行+2w,后向coordinate回复done
- 二阶段:coordinate向participant发出commit指令,participant执行提交,回复ack
异常场景
二阶段提交需要注意的问题
二阶段提交过程中还容易出现participantA接收到commit而participantB没有,如产生这种故障需要回滚整个事务,随之而来的问题是A的用户端可能看见账户减少2w又增加2w,会对用户产生动摇,为了解决这个问题,二阶段提交一般会在锁下进行,事务进行过程中用户访问会被拒绝,随之而来的问题是可用性问题,容易产生阻塞
三阶段提交
为了解决二阶段的阻塞问题,提出三阶段提交
MVCC
为了避免二阶段提交带来的性能问题和网络愤青场景带来的数据一致性问题,提出MVCC
锁
- 悲观锁和乐观锁
- 乐观锁:不上锁,在执行更新时判断别人是否修改数据,只有冲突时才放弃操作,乐观锁可以读数据,但是执行写操作的时候可能成功可能失败
- 悲观锁:操作数据时直接把数据锁住,直到操作完成后才会释放锁;锁住期间拒绝其他操作 锁可以保护处于中间状态的数据
MVCC
有没有更好的方法替换锁-MVCC(多版本控制)
- turetimeAPI:卫星时钟时序接口,方便实现lamport时序
- 物理时钟:提供TrueTime API,有Master节点维持一个绝对时间,保证各个服务器之间时钟误差控制在ϵ内,通常ϵ<7ms。
- 逻辑时钟:中心化授时的方式--时间戳预言机(TSO),好处是无需硬件的支持
共识协议
Quorum NWR模型
一种工程上常用的分布式模型
引起的问题:并发更新
RAFT协议
RAFT运作机制
双主问题的解:利用lamport逻辑时钟的tickline,即旧王驾崩新王才能登基
Paxos协议
分布式实践
MapReduce
统计超大文本或者多文本文件的单词出现次数
- Input:输入
- Mapper:把Input拆分成一个一个隔离的Mapper,并行处理
- Shuffler:把Mapper打乱,防止数据倾斜
- Reducer:卷据汇总
- 调度中心服务:解决调度问题
- 容错机制:类似于事务错误机制
分布式KV
如何存储大规模K-V对
因为K-V存储是个在线服务,所以会有一个弹性的问题