网站建设介绍ppt模板下载,网页游戏手机怎么才可以玩,网站备案时核验单,网页升级访问永久你懂的正文 虽然本人在前面也写过好几篇分布式系统相关的文章#xff0c;主要包CAP理论#xff0c;分布式储存与分布式事务#xff0c;但对于分布式系统#xff0c;并没有一个跟清晰的概念。分布式系统涉及到很多的技术、理论与协议#xff0c;很多人也说#xff0c;分布式系统…正文 虽然本人在前面也写过好几篇分布式系统相关的文章主要包CAP理论分布式储存与分布式事务但对于分布式系统并没有一个跟清晰的概念。分布式系统涉及到很多的技术、理论与协议很多人也说分布式系统是“入门容易深入难”我之前的学习也只算是管中窥豹只见得其中一斑。因此一致希望能对分布式系统有一个更全面的认识至少能够把分布式系统中的各个技术、理论串起来了解他们在分布式系统分别解决什么问题有哪些优秀的实现。 我曾在网络上搜索过”如何学习分布式系统“也在知乎上关注了该话题但并没有看到一个全面的、有指导意义的答案。本文的目标是给打算全面学习分布式系统的自己、以及感兴趣的读者指明一条可行的路径使得之后的学习不再盲目。 不过我并没有越过这座山我只是站在山前从前人留下的痕迹揣测山的全貌与沟壑臆想的成分居多还望各位大师指点迷津。 什么是分布式系统
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器处理更多的数据。 首先需要明确的是只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候且硬件的提升加内存、加磁盘、使用更好的CPU高昂到得不偿失的时候应用程序也不能进一步优化的时候我们才需要考虑分布式系统。因为分布式系统要解决的问题本身就是和单机系统一样的而由于分布式系统多节点、通过网络通信的拓扑结构会引入很多单机系统没有的问题为了解决这些问题又会引入更多的机制、协议带来更多的问题。。。 在很多文章中主要讲分布式系统分为分布式计算computation与分布式存储storage。计算与存储是相辅相成的计算需要数据要么来自实时数据流数据要么来自存储的数据而计算的结果也是需要存储的。在操作系统中对计算与存储有非常详尽的讨论分布式系统只不过将这些理论推广到多个节点罢了。 那么分布式系统怎么将任务分发到这些计算机节点呢很简单的思想分而治之即分片partition。对于计算那么就是对计算任务进行切换每个节点算一些最终汇总就行了这就是MapReduce的思想对于存储更好理解一下每个节点存一部分数据就行了。当数据规模变大的时候Partition是唯一的选择同时也会带来一些好处 1提升性能和并发操作被分发到不同的分片相互独立 2提升系统的可用性即使部分分片不能用其他分片不会受到影响 理想的情况下有分片就行了但事实的情况却不大理想。原因在于分布式系统中有大量的节点且通过网络通信。单个节点的故障进程crash、断电、磁盘损坏是个小概率事件但整个系统的故障率会随节点的增加而指数级增加网络通信也可能出现断网、高延迟的情况。在这种一定会出现的“异常”情况下分布式系统还是需要继续稳定的对外提供服务即需要较强的容错性。最简单的办法就是冗余或者复制集Replication即多个节点负责同一个任务最为常见的就是分布式存储中多个节点复杂存储同一份数据以此增强可用性与可靠性。同时Replication也会带来性能的提升比如数据的locality可以减少用户的等待时间。 下面这种来自Distributed systems for fun and profit 的图形象生动说明了Partition与Replication是如何协作的。 Partition和Replication是解决分布式系统问题的一记组合拳很多具体的问题都可以用这个思路去解决。但这并不是银弹往往是为了解决一个问题会引入更多的问题比如为了可用性与可靠性保证引用了冗余复制集。有了冗余各个副本间的一致性问题就变得很头疼一致性在系统的角度和用户的角度又有不同的等级划分。如果要保证强一致性那么会影响可用性与性能在一些应用比如电商、搜索是难以接受的。如果是最终一致性那么就需要处理数据冲突的情况。CAP、FLP这些理论告诉我们在分布式系统中没有最佳的选择都是需要权衡做出最合适的选择。 分布式系统挑战 分布式系统需要大量机器协作面临诸多的挑战 第一异构的机器与网络 分布式系统中的机器配置不一样其上运行的服务也可能由不同的语言、架构实现因此处理能力也不一样节点间通过网络连接而不同网络运营商提供的网络的带宽、延时、丢包率又不一样。怎么保证大家齐头并进共同完成目标这四个不小的挑战。 第二普遍的节点故障 虽然单个节点的故障概率较低但节点数目达到一定规模出故障的概率就变高了。分布式系统需要保证故障发生的时候系统仍然是可用的这就需要监控节点的状态在节点故障的情况下将该节点负责的计算、存储任务转移到其他节点 第三不可靠的网络 节点间通过网络通信而网络是不可靠的。可能的网络问题包括网络分割、延时、丢包、乱序。 相比单机过程调用网络通信最让人头疼的是超时节点A向节点B发出请求在约定的时间内没有收到节点B的响应那么B是否处理了请求这个是不确定的这个不确定会带来诸多问题最简单的是否要重试请求节点B会不会多次处理同一个请求。 总而言之分布式的挑战来自不确定性不确定计算机什么时候crash、断电不确定磁盘什么时候损坏不确定每次网络通信要延迟多久也不确定通信对端是否处理了发送的消息。而分布式的规模放大了这个不确定性不确定性是令人讨厌的所以有诸多的分布式理论、协议来保证在这种不确定性的情况下系统还能继续正常工作。 而且很多在实际系统中出现的问题来源于设计时的盲目乐观觉得这个、那个应该不会出问题。Fallacies_of_distributed_computing很有意思介绍了分布式系统新手可能的错误的假设 The network is reliable. Latency is zero. Bandwidth is infinite. The network is secure. Topology doesnt change. There is one administrator. Transport cost is zero. The network is homogeneous. 刘杰在《分布式系统原理介绍》中指出处理这些异常的最佳原则是在设计、推导、验证分布式系统的协议、流程时,最重要的工作之一就是思考在执行流程的每个步骤时一旦发生各种异常的情况下系统的处理方式及造成的影响。 分布式系统特性与衡量标准 透明性使用分布式系统的用户并不关心系统是怎么实现的也不关心读到的数据来自哪个节点对用户而言分布式系统的最高境界是用户根本感知不到这是一个分布式系统在《Distributed Systems Principles and Paradigms》一书中作者是这么说的 A distributed system is a collection of independent computers that appears to its users as a single coherent system. 可扩展性分布式系统的根本目标就是为了处理单个计算机无法处理的任务当任务增加的时候分布式系统的处理能力需要随之增加。简单来说要比较方便的通过增加机器来应对数据量的增长同时当任务规模缩减的时候可以撤掉一些多余的机器达到动态伸缩的效果 可用性与可靠性一般来说分布式系统是需要长时间甚至7*24小时提供服务的。可用性是指系统在各种情况对外提供服务的能力简单来说可以通过不可用时间与正常服务时间的必知来衡量而可靠性而是指计算结果正确、存储的数据不丢失。 高性能不管是单机还是分布式系统大家都非常关注性能。不同的系统对性能的衡量指标是不同的最常见的高并发单位时间内处理的任务越多越好低延迟每个任务的平均时间越少越好。这个其实跟操作系统CPU的调度策略很像 一致性分布式系统为了提高可用性可靠性一般会引入冗余复制集。那么如何保证这些节点上的状态一致这就是分布式系统不得不面对的一致性问题。一致性有很多等级一致性越强对用户越友好但会制约系统的可用性一致性等级越低用户就需要兼容数据不一致的情况但系统的可用性、并发性很高很多。 组件、理论、协议 假设这是一个对外提供服务的大型分布式系统用户连接到系统做一些操作产生一些需要存储的数据那么在这个过程中会遇到哪些组件、理论与协议呢 用一个请求串起来 用户使用Web、APP、SDK通过HTTP、TCP连接到系统。在分布式系统中为了高并发、高可用一般都是多个节点提供相同的服务。那么第一个问题就是具体选择哪个节点来提供服务这个就是负载均衡load balance。负载均衡的思想很简单但使用非常广泛在分布式系统、大型网站的方方面面都有使用或者说只要涉及到多个节点提供同质的服务就需要负载均衡。 通过负载均衡找到一个节点接下来就是真正处理用户的请求请求有可能简单也有可能很复杂。简单的请求比如读取数据那么很可能是有缓存的即分布式缓存如果缓存没有命中那么需要去数据库拉取数据。对于复杂的请求可能会调用到系统中其他的服务。 承上假设服务A需要调用服务B的服务首先两个节点需要通信网络通信都是建立在TCP/IP协议的基础上但是每个应用都手写socket是一件冗杂、低效的事情因此需要应用层的封装因此有了HTTP、FTP等各种应用层协议。当系统愈加复杂提供大量的http接口也是一件困难的事情。因此有了更进一步的抽象那就是RPCremote produce call是的远程调用就跟本地过程调用一样方便屏蔽了网络通信等诸多细节增加新的接口也更加方便。 一个请求可能包含诸多操作即在服务A上做一些操作然后在服务B上做另一些操作。比如简化版的网络购物在订单服务上发货在账户服务上扣款。这两个操作需要保证原子性要么都成功要么都不操作。这就涉及到分布式事务的问题分布式事务是从应用层面保证一致性某种守恒关系。 上面说道一个请求包含多个操作其实就是涉及到多个服务分布式系统中有大量的服务每个服务又是多个节点组成。那么一个服务怎么找到另一个服务的某个节点呢通信是需要地址的怎么获取这个地址最简单的办法就是配置文件写死或者写入到数据库但这些方法在节点数据巨大、节点动态增删的时候都不大方便这个时候就需要服务注册与发现提供服务的节点向一个协调中心注册自己的地址使用服务的节点去协调中心拉取地址。 从上可以看见协调中心提供了中心化的服务以一组节点提供类似单点的服务使用非常广泛比如命令服务、分布式锁。协调中心最出名的就是chubbyzookeeper。 回到用户请求这个点请求操作会产生一些数据、日志通常为信息其他一些系统可能会对这些消息感兴趣比如个性化推荐、监控等这里就抽象出了两个概念消息的生产者与消费者。那么生产者怎么讲消息发送给消费者呢RPC并不是一个很好的选择因为RPC肯定得指定消息发给谁但实际的情况是生产者并不清楚、也不关心谁会消费这个消息这个时候消息队列就出马了。简单来说生产者只用往消息队列里面发就行了队列会将消息按主题topic分发给关注这个主题的消费者。消息队列起到了异步处理、应用解耦的作用。 上面提到用户操作会产生一些数据这些数据忠实记录了用户的操作习惯、喜好是各行各业最宝贵的财富。比如各种推荐、广告投放、自动识别。这就催生了分布式计算平台比如HadoopStorm等用来处理这些海量的数据。 最后用户的操作完成之后用户的数据需要持久化但数据量很大大到按个节点无法存储那么这个时候就需要分布式存储将数据进行划分放在不同的节点上同时为了防止数据的丢失每一份数据会保存多分。传统的关系型数据库是单点存储为了在应用层透明的情况下分库分表会引用额外的代理层。而对于NoSql一般天然支持分布式。 一个简化的架构图 下面用一个不大精确的架构图尽量还原分布式系统的组成部分不过只能体现出技术不好体现出理论 概念与实现 那么对于上面的各种技术与理论业界有哪些实现呢下面进行简单罗列。 当然下面的这些实现小部分我用过知其所以然大部分听说过知其然还有一部分之前闻所未闻分类也不一定正确只是从其他文章抄过来的。罗列在这里以便日后或深或浅的学习。 负载均衡 Nginx高性能、高并发的web服务器功能包括负载均衡、反向代理、静态内容缓存、访问控制工作在应用层 LVS Linux virtual server基于集群技术和Linux操作系统实现一个高性能、高可用的服务器工作在网络层
webserver JavaTomcatApacheJboss Pythongunicorn、uwsgi、twisted、webpy、tornado
service SOA、微服务、spring bootdjango
容器 dockerkubernetes
cache memcache、redis等
协调中心 zookeeper、etcd等 zookeeper使用了Paxos协议Paxos是强一致性高可用的去中心化分布式。zookeeper的使用场景非常广泛之后细讲。
rpc框架 grpc、dubbo、brpc dubbo是阿里开源的Java语言开发的高性能RPC框架在阿里系的诸多架构中都使用了dubbo spring boot
消息队列 kafka、rabbitMQ、rocketMQ、QSP 消息队列的应用场景异步处理、应用解耦、流量削锋和消息通讯
实时数据平台 storm、akka
离线数据平台 hadoop、spark PS: apark、akka、kafka都是scala语言写的看到这个语言还是很牛逼的
dbproxy cobar也是阿里开源的在阿里系中使用也非常广泛是关系型数据库的sharding replica 代理
db mysql、oracle、MongoDB、HBase
搜索 elasticsearch、solr
日志 rsyslog、elk、flume 总结 写这篇文章我曾在网络上搜索过“如何学习分布式系统”但实话说没有很认同的答案。也许这确实是一个难以回答的问题。于是我想自己写出一个答案但写完这篇文章感觉自己的回答也很混乱也没有说清楚不过对我自己还是有一些指导意义的比如理清了分布式系统中会遇到的各种技术、理论、协议以及通过一个例子展示他们是如何协作的接下来就是各个击破了。 网上的诸多回答上来就是看各种论文google三大件、paxos什么的个人觉得不是很实用。更好的过程是先有一个整体的把握然后自己思考会有什么问题带着问题去寻求答案在寻求答案的时候再去看论文。 另外也有很多人提到掌握好计算机基础知识如操作系统、计算机网络对学习分布式系统是大有裨益的这一点我很赞同。分布式系统解决问题的思路是早就有的很多都是前人研究透的问题思想都是相同的。比如函数式编程中的map reduce之于Hadoop的MapReduce比如磁盘存储的raid之于Partition与Replication比如IPC之于消息队列。