分布式详解

分布式系统简介:

分布式系统是由一组通过网络进行通信.为了完成共同的任务而协调工作的计算机节点组成的系统.分布式系统的出现是为了用廉价的 普通的机器完成单个计算机完成的计算 存储任务.目的是利用更多地机器.处理更多地数据.

为了节省成本.会首先利用单机系统(流量特别大的除外).只有当单个节点的处理能力无法满足日益增长的计算 存储任务的需求.硬件的提升(加内存 加磁盘 使用更好的CPU)费用高昂到得不偿失的程度.且应用程序也不能进一步优化的时候.才需要考虑分布式系统.分布式系统要解决的问题本身就和单机系统一样.由于分布式系统多节点.通过网络通信的拓扑结构.会引入很多单机系统没有的问题,为了解决这些问题又会引入更多地规则协议.带来更多地问题.

分布式系统分为分布式计算与分布式存储.计算与存储是相辅相成的.计算需要数据.数据要么来自实时数据(流数据).要么来自存储的数据.而计算的结果也需要存储的.在操作系统中.对计算与存储有非常详细的讨论.分布式系统只不过是将这些理论推广到多个节点.

分布式系统是通过分而治之将任务分发到这些计算机节点的.对于计算来说.就是计算多个任务进行切换执行.每个节点计算一些.最终汇总就行了.这就是MapReduce思想.

MapReduce是一种编程模型.用于大规模数据集(大于1TB)的并行运算.概念Map(映射)和Reduce(归约)是它的主要思想.并借鉴了函数式编程语言和矢量编程语言的特性.MapReduce极大的方便了在不会分布式系统的情况下.将程序运行在分布式系统上.

分布式存储是一种数据存储技术.通过网络使用企业每台机器上的磁盘空间.并将这些分散的存储资源构成一个虚拟的存储设备.将数据分散的存储在企业的各个角落.在大数据环境下.元数据的体量也非常大.元数据的存取性能是整个分布式文件系统性能的关键.当数据规模变大的时候.分片是唯一的选择.同时也会带来下面的好处.

1).提升性能和并发.操作被分发到不同的切片.相互独立.

2).提升系统的可用性.即使部分分片不能用.其它分片也不会受到影响.

理想情况下.有切片就行.实际效果不太理想.分布式系统中有大量的节点.且通过网络通信.单个节点的故障(如进程crash 断电 磁盘损坏等)是小概率事件.但整个系统的故障会随着节点的增加而呈指数级增加.网络通信也可能出现断网 高延迟的情况.在这种一定会出现的"异常"情况下.分布式系统还是需要继续稳定的对外提供服务.即需要较强的容错性.最简单的办法就是采用冗余或者复制集.即多个节点负责同一个任务.在分布式署存储中.多个节点负责存储同一份数据.以此增强可用性与可靠性.同时.复制集也会带来性能的提升.比如数据的locality可以减少用户的等待时间.

分片和复制集是解决分布式系统问题的一记组合拳.很多具体的问题都可以用这个思路解决.这并不是一个万能的解决方案.往往是解决了一个问题.会引入更多地问题.比如.为了可用性和可靠性保证.引用了冗余的复制集.有了冗余.各副本间的一致性问题就变的很复杂.一致性对于系统的角度和用户的角度又有不同的等级划分.如果要保证强一致性.则会影响可用性与性能.如果是最终一致性.就需要处理数据冲突的情况.

CAP是指一个分布式系统最多能同时满足一致性 可用性和分区容错性这三项中的两项.在理论计算机科学中.CAP定理又被称作布鲁尔定理.它指出对于一个分布式系统来说.不可能同时满足以下三点.

一致性.等同于所有节点访问同一份最新的数据副本.

可用性.每次请求都能获取到非错的响应,但是不保证获取的数据是最新的数据.

分区容错性.以实际效果而言.分区相当于对通信时限要求.系统如果不能在时限内达成数据一致性.就意味着发生了分区的情况,必须就当前操作在一致性和可用性之间做出选择.

通过FLP不可能原理 CAP定理等理论可知,在分布式系统中.没有最佳的选择.都是需要权衡.做出最合适的选择.

分布式系统挑战:

异构的机器与网络:

分布式系统中的机器.配置不一样.其运行的服务也可能由不同的语言 架构实现.因此处理能力也不一样.节点间通过网络连接.而不同网络运营商提供网络的带宽 延时 丢包率又不一样.怎么保证起头并进,共同完成目标.是个不小的挑战.

普遍的节点故障:

虽然单个节点故障率较低.但节点数目达到一定规模后.出故障的概率就变高了.分布式系统需要保证故障发生的时候.系统仍然是可用的.这就需要监控节点的状态.在节点出现故障的情况下将该节点负责的计算 存储任务转移到其它节点.

网络通信问题:

可能的网络通信问题包括网络分割 延时 丢包 乱序等.相比单机的过程调用.网络通信最麻烦的是延时.节点A向节点B发出请求.在约定的时间内没有收到节点B的响应.那么节点B是否处理了请求.这是不确定的.不确定会带来诸多问题.比如.是否要重试请求.节点B会不会多处理同一个请求.

分布式系统的挑战来自不确定性.不确定计算机什么时候crash 断电.不确定磁盘什么时候损坏.不确定每次网络通信要延迟多久,也不确定通信对端是否处理了发送的消息.不确定是令人讨厌的.所以有很多的分布式理论 协议来保证在这种不确定性的情况下.系统还能正常工作.

分布式系统特性与衡量标准:

透明性:

使用分布式系统的用户不关心系统是怎么实现的.也不关心读取的数据来自哪个节点.对用户而言.分布式系统的最高境界是用户根本感知不到这是一个分布式系统.

可扩展性:

分布式系统的根本目标就是为了处理单个计算机无法处理的任务.当任务增加的时候.分布式系统的处理能力需要随之增加.简单来说.要比较方便的通过增加机器来应对数据量的增长.同时.当任务规模缩减的时候.可以撤掉一些多余的机器.以达到动态伸缩的效果.

可用性与可靠性:

一般来说.分布式系统是需要长时间甚至7×24小时提供服务.可用性是指系统在各种情况下对外提供服务的能力.简单来说.可以通过不可用时间与正常服务时间的比值来衡量.而可靠性是指计算成功正确 存储的数据不丢失.

高性能:

不管是单机还是分布式系统.都非常关注性能.不同的系统对性能的衡量指标是不同的.例如高并发.单位时间内处理的任务越多越好.低延迟.每个任务的平均时间越少越好.

一致性:

分布式系统为了提高可用性和可靠性.一般会引入冗余(复制集).如何保证这些节点的状态一致.这就是分布式系统不得不面对的一致性问题.一致性有很多等级.一致性越强.对用户越友好.但会制约系统的可用性.一致性等级越低.用户就需要兼容数据不一致的情况.系统的可用性和并发性会高很多.

分布式常用组件:

用户在使用Web APP SDK时.是通过HTTP TCP连接到系统.在分布式系统中.为了高并发 高可用.一般都是多个节点提供相同的服务.第一个问题就是选择哪个服务呢.这个就是负载均衡.负载均衡的使用非常广泛.在分布式系统.大型网站的方方面面都有使用.只要涉及多个节点提供同质的服务就需要负载均衡.

通过负载均衡找到一个节点.接下来就是处理用户的请求.请求有可能很简单.也有可能很复杂.简单的请求.比如读取数据.那么很可能有缓存.即分布式缓存.如果缓存没有命中.则需要去数据库读取数据.对于复杂的请求.可能会调用系统中的其他服务.

假设服务A需要调用服务B.首先需要两个节点通信.网络通信是建立在TCP/IP协议的基础上.如果每个应用都手写Socket是一件低效且冗杂的事情.这时候就需要应用层的封装.因此有了HTTP FTP等各种应用层协议.当系统变得复杂.提供了大量的HTTP接口也是困难的事情.因此有了进一步的抽象.那就是RPC.RPC基本就跟本地调用一样方便.屏蔽了网络通信等诸多细节.增加新的接口也更方便.

一个请求可能包含诸多操作.即在服务A上做一些操作.然后在服务B上做另一些操作.比如简化版的网络购物.在订单服务上发货.在账户服务上扣款.这两个操作需要保证原子性.要么都成功要么都不成功.这就涉及分布式事务的问题.分布式事务是从应用层面保持一致性的.

上面说到一个请求包含多个操作.其实就是涉及多个服务.分布式系统中有大量的服务.每个服务又是由多个节点组成.那么一个服务怎么找到另一个服务(某个节点)?通信是需要地址的.怎么获取这个地址.简单的方法就是将地址写入到一个固定的配置文件.或者写入数据库.但这些方法在节点数据巨大 节点动态增删的时候都不方便.这个时候就需要服务的注册与发现.提供服务的节点向一个协调中心注册自己的地址.使用服务的节点去协调中心读取地址.

从上可以看出.协调中心提供了中心化服务.以一组节点提供类似单点的服务.使用非常广泛.比如命令服务 分布式锁等.协调中心比较常用的是Zookeeper.

用户的请求操作会产生一些数据 日志等.同时其他一些系统可能会对这些消息感兴趣.比如个性化推荐 监控等.这里就抽象出了两个概念.消息的生产者与消息的消费者.生产者怎么把消息传递给消费者呢.RPC并不是一个好的选择.因为RPC得指定消息发给谁.但实际这些情况并不可知.这个时候就需要消息队列了.

上面提到.用户操作会产生一些数据.这些数据记录了用户的操作习惯 喜好等.是各行各业的财务.比如各种推荐 广告投放 自动识别等.这些催生了分布式计算平台.比如Apache基金会开发的Hadoop Storm等.用来处理海量数据.

最后.用户的操作完成之后.用户的数据需要持久化.但数据量依然很大.大到单个节点无法存储.则这个时候就需要分布式存储.将数据进行划分在不同的节点上.同时.为了防止数据的丢失.每一份数据会保存多份.传统的关系数据库是单点存储.为了在应用层透明的情况下分库分表.会引用额外的代理层.而对于NoSql.大多数都支持分布式.

分布式系统常见一致性算法:

Paxos算法:

Paxos算法是莱斯利 兰伯特于1990年提出的一种基于消息传递具有高度容错特性的共识算法.Paxos算法是基于消息传递且具有高度容错特性的一致性算法.是目前公认的解决分布式一致性问题最有效的算法之一.

分布式系统中的节点通信存在两种模型.共享内存和消息传递.基于消息传递通信模型的分布式系统.不可避免的会发生以下错误.进程可能会慢 被杀死或者重启.消息可能会延迟 丢失重复.在基础Paxos场景中.先不考虑可能出现消息篡改即拜占庭错误的情况.Paxos算法解决的问题是一个可能发生上述异常的分布式系统中如何就某个值达成一致.保证不论发生以上任何异常.都不会破坏决议的共识.一个典型的场景是.在一个分布式系统中.如果各节点初始状态一致.每个节点都执行相同的操作序列.则它们最后都能得到一个一致的状态.为保证每个节点执行相同的命令序列.需要在每一条指令上执行一个"共识算法"以保证每个节点看到的指令一致.一个通用的共识算法可以应用在许多场景中.是分布式计算中重要的问题.

为描述Paxos算法.Lamport虚拟了一个叫做Paxos岛的希腊城邦.这个岛按照议会民主制的政治模式制定法律.但是没有人愿意将自己的全部时间和精力放在这种事情上.所以无论是议员.议长或者传纸条的服务员都不能承诺别人需要时一定会出现.也无法承诺批准决议或者传递消息的时间.但是这里假设没有拜占庭错误.即虽然有可能一个消息被传递了两次.但是绝对不会出现错误的消息.只要等待足够的时间.消息就会被传到.另外.Paxos岛上的议员是不会反对其他议员提出的决议的.

对于分布式系统.议员相当于各节点.制定的法律相当于系统的状态.各节点需要进入一个一致的状态.例如在独立Cache的对称多处理器系统中.各处理器读取内存的某个节点.必须读取同样的一个值.否则系统就违背了一致性的要求.一致性要求相当于法律条文只能有一个版本.议员和服务员的不确定性相当于节点和消息传递通道的不可靠性.

Raft协议:

Raft是一种用于替代Paxos的共识算法.相比如Paxos.Raft的目标是提供更清晰的逻辑分工使得算法本身能被更好的理解.同时它安全性更高.并能提供一些额外的特性.Raft能为在计算机集群之间部署有限状态机提供一种通用的方法.并确保集群内的任意节点在某种状态转换上保持一致.

Raft是一种为了管理复制日志的一种一致性算法.它提供了和Paxos算法相同的功能和性能.但是它的算法结构和Paxos不同.使得Raft算法更加容易理解并且更容易构建实际的系统.为了提升可理解性.Raft将一致性算法分解成了几个关键模块.例如领导人选举 日志复制和安全性.同时它是通过实施一个更强的一致性来减少需要考虑的状态数量.相对来说.Raft算法更容易学习理解.Raft算法还包括一个新的机制来允许集群成员的动态改变.它利用重叠的大多数来保证安全性.

Raft特性:

强领导者:

和其他一致性算法相比.Raft使用一种更强的领导能力形式.比如.日志条目只从领导者发送给其他的服务器.这种方式简化了对复制日志的管理并且使得Raft算法更加易于理解.

领导选举:

Raft算法使用一个随机计时器来选举领导者.这种方式只是在任何一致性算法都必须实现的心跳机制上增加了一点机制.在解决冲突的时候会更加简单快捷.

成员关系调整:

Raft使用一种共同一致的方法来处理集群成员变换的问题.在这种方法下.处于调整过程中的两种不同的配置集群中大多数机器会有重叠.这就使得集群在成员变换的时候依然可以继续工作.

语雀地址www.yuque.com/itbosunmian...?

《Go.》 密码:xbkk 欢迎大家访问.提意见.

相关推荐
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第38题:两个对象的hashCode()相同,则 equals()是否也一定为 true?
java·开发语言·后端·面试·hash-index
SamDeepThinking1 小时前
所有的框架源码,最怕的就是被debug
java·后端·程序员
kree2 小时前
通义千问 SSE 流式:累计文本 vs 增量 Delta
后端
fox_lht2 小时前
第十一章 错误处理
开发语言·后端·rust
焗猪扒饭2 小时前
极简案列入门golang依赖注入工具wire
后端·go
M ? A2 小时前
Vue 转 React | VuReact 实时监听开发指南
前端·vue.js·后端·react.js·面试·开源·vureact
贺国亚2 小时前
Kafka系统设计与编码
后端·kafka
南方的耳朵3 小时前
谨慎使用git rebase --onto A B C
后端