学习分布式系统需要怎样的知识

分布式架构(3)
由于分布式系统所涉及到的领域众多,知识庞杂,很多新人在最初往往找不到头绪,不知道从何处下手来一步步学习分布式架构。
本文试图通过一个最简单的、常用的分布式系统,来阐述分布式系统中的一些基本问题。
分布式缓存
分布式文件系统/CDN
分布式数据库/Nosql
分布式消息中间件
分布式session问题
下图为一个中大型网站/App的基本架构:
在这个架构中,涉及到以上所列的基本问题:
负载均衡是分布式系统中的一个最最基本的问题。在上图中:
网关需要把请求分发给不同的Tomcat;
Tomcat需要把收到的请求,分发给不同的Service;
这都需要负载均衡。一句话:凡是请求从一个入口进来,需要分发给后端不同的机器时,就需要负载均衡。
局域网负载均衡
在上图中,负载均衡发生在局域网内部。在这里,常用的网关软件有Nginx/HAProxy/F5/LVS/各种云上的SLB等。
广域网负载均衡
在上图之外,还有广域网负载均衡。这通常发生在域名服务器上,而不是局域网内部。
同1个域名,映射到不同的局域网集群。
负载均衡算法
常用的负载均衡算法:随机,轮询(Round Robin),最小资源数,hash。
分布式缓存
在上图中,当DB负载过高,我需要为Service机器加缓存时,就遇到一个基本问题:
如果使用local的内存做缓存,则其他Service机器就没办法共用此缓存。
因次,我需要一个可以让所有Service机器共享的缓存,这就是分布式缓存。
常用的分布式缓存组件:Memcached/Redis/Tair等
分布式文件系统
在上图中,当我要存储客户端上传的图片文件时,就会遇到另一个基本问题:我不能把图片存在每个Tomcat的本地文件系统里面,这样的话,其他机器就没办法访问了。我需要一个让所有机器可以共享的文件系统,这就是分布式文件系统。
常用的分布式文件系统:MogileFS/TFS/HDFS/Amazon S3/OpenStack Swift等
当使用了分布式文件系统,对外提供图片url访问服务时,就会遇到另一个基本问题:如果每次文件的访问,都要到分布式文件系统里面去取,效率和负载就可能成为问题。
为此,就需要引入CDN。
常用的CDN厂商,比如ChinCache。当然,现在的各种云存储,比如七牛云,阿里云,腾讯云,已经自带了CDN。
分布式系统的一个基本问题就是:机器与机器之间如何通信? 我们都知道底层原理是TCP/IP,Socket。
但一般很少有人会去裸写Socket,实现机器之间的通信。这里,最常用的组件就是RPC。
最简单的实现RPC的方式就是使用http。当然,业界有很多成熟的开源RPC框架,如Facebook的Thrift,
阿里的Dubbo,点评的Pigeon。。
在RPC内部,一般都自己实现了负载均衡。还有更复杂的,如多版本,服务降级等。
补充一句:虽然底层原理都是Socket,但使用不同框架/组件时,通常都有其自己的跨机器通信方式,比如Mysql JDBC,RPC, 消息中间件等。
分布式数据库
在上图中,DB是单一节点。当访问量达到一定程度,就会涉及到Mysql的分库分表问题。
分库/分表之后,就会涉及到join的问题,分布式事务的问题。
关于分库分表,业界也早有成熟方案。对上层屏蔽分库分表,sql的执行,像是在单库一样。
还有像MongoDB这种Nosql数据库,天生是分布式的。但同样会面对Mysql分库分表所要面对的问题。
还有像阿里的OceanBase,有Mysql的强一致性保证,又是分布式的,还可以支持分布式事务。
分布式消息中间件
在上图中,没有提及到消息中间件。相对其他基本问题,这个需要一个更适合的业务场景来谈,在以后的章节中,会再详述。
常用的消息中间件,比如老一辈的ActiveMQ/RabbitMQ, 新一点的,阿里的RocketMQ,LinkedIn的Kafka等。
消息中间件的一个典型场景就是:通过最终一致性,解决上面的分布式事务问题。
分布式session问题
在传统的单机版应用中,我们经常使用session。而当单机扩展到多机,单机的session就没办法被其他机器所访问。
此时就需要使用分布式session,把session存放在一个所有Tomcat都可以访问的地方。
关于分布式session,业界早有成熟方案,在此不再详述。
本文罗列了分布式系统的各种基本问题和业界常用的技术,希望建立起分布式系统的一个宏观图谱。
后续,会针对各个领域,逐个剖析!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11658次
排名:千里之外
原创:39篇
评论:13条
(11)(7)(27)长期以来学习掌握系统的知识非常庞杂混乱,本文将算法归纳为几种:计时模型 进程间通讯interprocess communication 和失败模型failure model。计时模型timing model计时模型分同步 异步和部分同步三种,这几种模型都有时间计时这个共同特点。同步模型是直接调用执行,组件之间同时按步骤执行,这个模型的问题是无法反映现实情况,甚至在情况下很少有真正同步,比如过去RPC(远程过程调用)等都是两个服务器之间的代码方法直接相互调用,这种问题带来相互堵塞各种服务器进程,现在服务器之间都是通过发送消息实现通讯,让发送消息变成同步几乎很难。同步模型好处是能完成理论上测试结果,比如,因为同步模型有时间上的保证,我们可以看看一个问题在同步模型下是否能够解决,如果在有时间保证的机制下都不能解决,意味着在没有时间保证的机制也是不可能解决的。异步模型有点复杂,组件之间的动作是按照它们自己的顺序要求进行的,也不提供任何关于采取这些行动的时间上与速度的保证,这个模型更接近于现实情况,但是也不是完美的,比如一个进程会需要无限循环来响应一个请求,在真实项目中,我们可能会强加一个计时timeout,一旦超过这个timeout,将会退出这个请求的处理,这就带来了问题,如果确保一个进程活跃的条件?也就是说,如何知道一个进程是需要无限循环活跃的,而其他进程则是不需要,需要timeout去中断的,这里面哪个是业务需要,哪个是因为故障导致的呢?在部分同步模型中大部分访问同步时钟,有关于传递消息有多长的限制,有一个进程执行一个步骤需要多长时间的限制。进程间通讯进程之间是如何通讯的,这里有消息传递模型和共享内存模型,前者是通过消息发送通讯,后者是访问内存中共享变量共享数据进行通讯。这里进程有服务器 节点的意思,一个进程可能代表场景的一台服务器。消息传递最难的是不能发送重复消息,每次只能精确一次传递,这里有很多设计,比如Perfect Links 抽象可以保证,但是它不能正常反映现实世界,虽然不真实,但是有用,我们可以使用Perfect Links 证明一个问题不可能被解决,然后我们就知道其他相关问题也没有答案。消息传递总是可以被想象为FIFO之类队列或堆栈。共享内存是我们编程常用的方式,需要在一台服务器内才能完成。我们可以使用消息传递算法完成情况下的内存共享对象,比如读写注册器,调用一个服务之间需要查询这个服务在哪个服务器上,负载平衡器也是一个读写注册器,是一个全局共享的内存。失败模型分布式模型总是必须考虑进程失败的情况,在crash-stop失败模型中,一个进程假设为一直是正确,直至它崩溃,一旦它崩溃,就永远不会恢复;也有crash-recovery 模型,进程能够在失败以后恢复,在这种情况下,一些算法来保证进程恢复到其失败之前的状态,这可以通过从持久层读取状态完成,或者通过和一个集群小组中的其他进程通讯方式完成。注意这里有不同集群组算法,一个进程崩溃后,恢复其状态的进程不会再被认为是之前同样的进程,这取决于动态组还是固定组这两种算法。失败模型也包括:一个进程如果无法接受和发送消息,被称为遗漏omission failure mode,遗漏模型也有不同种类,一个进程无法接受和发送消息很重要吗?想象一组进程实现一个,如果一个进程无法回复同一组的其他进程,即使能够接受来自它们的请求,这也意味着这个进程能够接受外部消息更新自己的状态,其实也就意味着它能回复来自客户端的读请求,也就是说,虽然它自己不能主动回复客户端的请求,但是可以接受客户端的主动读取请求。一个复杂失败模型是拜占庭Byzantine 或称为任意失败模型,进程会发送错误信息到对方,它们会模仿发送正确数据,但是实际已经篡改了本地数据库的内容。设计系统时,我们需要对付这些失败模型。失败探测我们希望在进程崩溃失败时及时发现,比如crash-stop失败模型加上同步系统,我们能够使用timeout;如果我们定期让进程ping到一个专门的失败探测器,我们就能精确知道那个进程是否正常,如果过了timeout时间没有Ping访问,那么我们就可以认为那台进程服务器崩溃了。更真实情况是,假设一个消息到达目标需要确定的时间,确定好一个进程执行一个步骤需要多长时间,那么就可以使用timeout进行衡量计算。失败模型探测有两个属性策略:1. Strong Completeness强完整性:每个失败的进程会永久被其他正确进程怀疑。2.Eventual Strong Accuracy最终强精确度,没有一个进程被任何正确的进程怀疑。当一个进程被其他进程怀疑时,这些进程就不可能达成共识consensus ,而在系统中使用异步模型是必须要达成共识,也就是每个进程内部状态通过异步消息传递后,最终其他进程的状态会和最初发送消息的那个进程内部状态一致,这称为达成共识,但是因为有进程存在失败崩溃的可能,所以,在这个达成共识的消息传递过程中,如何确保进程之间的信任,不怀疑对方,从而确保消息传递成功,那么引入失败探测器是可以规避这个问题的。领导人选举LEADER ELECTION这是通过决定某个进程没有崩溃失败,能够正常工作,那么这个进程就可以被网络中其他进程信任,它就可以被认为是领导人,负责协调动作,这种协议有Raft和Zab两种。这种机制会导致瓶颈集中在领导人那里,而且之前还需要领导人选举,这些多余过程可能是我们不需要的。一致共识CONSENSUS共识是在独立进程之间达成一致的统一意见,这些进程会就某个问题建议一个数值,基于这个推荐的值会同意采取一致行动,比如,一个轿车有各种传感器提供制动器温度的信息,依赖于传感器的精度,会有不同变化的数值,但是ABS计算机需要知道施加多大压力到制动器上,这种共识问题每天生活中都发生。一个进程实现共识是通过暴露带有推荐和决定功能的API实现的,一个进程会推荐数值,由此开始共识,然后它得基于一个数值决定,这个数值是在整个系统中被推荐了的,这些算法包括:Termination, Validity, Integrity 和Agreement.1.Termination: 每个正确的进程最终会决定某个数值。2.Validity: 如果一个进程决定了v,那么v会被其他进程推荐。3.Integrity: 没有进程能够决定两次4.Agreement: 没有两个正确进程有不同的决定。法定人数QUORUMSQuorums 是一个设计失败容错系统的工具,当系统存在crash-failure模型时,总是有一个法定人数代表大多数意见从而进行决策的,因为崩溃失败的总是少数。比如有N个进程服务器,假设崩溃的进程是少数,比如N/2-1个进程崩溃,也就是49%的进程崩溃,我们还是有51%的会投赞成票。Raft协议使用的是这种大多数策略,根据提交到系统的日志来判断,分布式系统的时间理解时间和其导致的因果是系统的大问题,我们通常用事件这个概念代表生活中发生的那些事实,使用happened before顺序约束定义这些事件,但是我们有很多进程交换信息,共同访问共享资源等等,我们如何告诉某个进程事件的happened before策略呢?也就是谁在前谁在后的顺序呢?为了回答这个问题,进程需要共享一个同步的时钟,精确知道它在网络间移动花费多长时间?包括CPU调度任务的时间等等,显然这在真实世界是不可能实现的。引入了逻辑时钟概念,逻辑时钟是一个分配一个数字给事件的方式,也就是说,这些数字不是和实际时间有关,但是和一个节点的进程事件有关。有各种逻辑时钟,比如 Vector Clocks向量时钟或 Interval Tree Clocks.理解时间问题,必须理解一个重要概念:同时性这个想法有时我们必须放弃(The idea of simultaneity is something we have to let go.),这是有关“绝对知识”等旧哲学信条的问题,他们认为绝对知识是可以到达的,其实人的认识是相对,永远不可能到达真正事物本质,你以为的同时性并不是真正同时性,光线也是有速度的,即使最快的光线也是需要时间才从一个地方到达另外一个地方。可见 一书中的“绝对与相对”。参考原文:
最佳分辨率
OpenSource
Code & 2002-20分布式学习环境的建构_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
分布式学习环境的建构
上传于||暂无简介
阅读已结束,如果下载本文需要使用2下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

 

随机推荐