【CC++服务器开发】中间件的含义及常用中间件介绍_第1页
【CC++服务器开发】中间件的含义及常用中间件介绍_第2页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

CC++服务器开发】中间件的含义及常⽤中间件介绍⼀、中间件的定义中间件这个术语第⼀次出现是1968年在德国加尔⽶施帕滕基兴举办的NATO软件⼯程⼤会结束后发表的⼀份报告中。这届⼤会正式确定了软件⼯程(SoftwareEngineering)的概念,同时还探讨了软件设计、⽣产和分发等主题。中间件(英语:Middleware),⼜译中间件、中介层,是⼀类提供系统软件和应⽤软件之间连接、便于软件各部件之间的沟通的软件,应⽤软件可以借助中间件在不同的技术架构之间共享信息与资源。中间件位于客户机服务器的操作系统之上,管理着计算资源和⽹络通信。–维基百科我们按照类别来看⼀些经常会遇到的⼀些不是中间件的概念-业务平台不是中间件,业务平台是从服务的视⾓抽象的能同时⽀撑多个业务,业务之间的信息能形成交互和增强的平台。-营销⼯具不是中间件,营销⼯具是直接作⽤于最终消费者⽤户的软件或者插件服务。-⼆⽅/三⽅⼯具包不是中间件,⼆⽅/三⽅⼯具包是在各种场景的程序开发过程中沉淀的⼀些常⽤⼯具类(功能)的集合,包含于软件代码本⾝。-SaaS不是中间件,SaaS(SoftwareasaService)更多的是⼀种软件交付模式,⽆需⽤户安装,通过⽹络在线访问的⼀种服务模式。-PaaS不是中间件,PaaS(PlatformasaService)将软件研发的平台做为⼀种服务,提供软件部署平台(强调的是屏蔽系统和软件细节的runtime平台)。从定义可以总结出评判的⼏个地⽅1.性质:中间件是软件。2.作⽤层级:系统软件和应⽤软件之间、软件各部件之间;管理客户机与系统软件之间的计算资源和⽹络通信。3.服务对象:中间件为应⽤软件服务,应⽤软件为最终⽤户服务,最终⽤户并不直接使⽤中间件。中间件能给客户带来什么?为上层应⽤软件的开发提供便捷的、开箱即⽤的服务交互和计算的能⼒,缩短开发周期;屏蔽底层runtime的差异;节省应⽤本⾝的系统资源,减少运⾏成本。什么时候使⽤中间件基于中间件的定义我们知道中间件是连接软件与系统之间的服务,那么我们什么时候使⽤了中间件,在哪些地⽅⽤到了中间件了。我们不妨假设⼀个http请求过程来窥视⼀番。当你在浏览器中输⼊⼀个⽹址时,它会通过DNS解析到⽬标服务注册的公⽹IP地址请求到达⽬标服务的web反向代理服务器Tengine之后,经过⼀定的过滤转发到⽬标服务A上服务A通过RPC框架Dubbo请求服务B的结果做中间计算,并且从Tair缓存中读取计算因⼦,计算结果服务A接着使⽤Druid通过TDDL写⼊计算结果到MySQLMaster节点然后返回结果异步过程中Canal通过模拟Binlog主从复制的原理,迅速将这条Binlog消费并下发到消息队列RocketMQ服务C通过RocketMQ消费到事件之后,通过配置中⼼ConfigServer拉取到的策略进⾏对应策略的事件处理。这个过程中我们使⽤了⼀系列的中间件来协同各个微服务完成整个流程,如web反向代理服务器Tengine、RPC框架Dubbo、缓存Tair、连接池Driud、数据库代理层TDDL、Binlog同步⼯具Canal、消息队列RocketMQ、配置中⼼ConfigServer。-路由与web服务器:处理和转发其他服务器通信数据的服务器。如被业界⼴泛使⽤的阿⾥基于Nginx研发的Tengine、阿⾥内部的集中式路由服务VipServer-RPC框架:微服务时代的远程服务调⽤框架。如grpc,Thrift,阿⾥的HSF,Dubbo,SOFA-RPC-消息中间件:⽀持在分布式系统之间发送和接收消息的软件。如Apachekafka,ApacheRabbitMQ,NSQ,阿⾥孵化开源的ApacheRocketMQ-缓存服务:分布式的⾼速数据存储层,⼀般是内存存储。如阿⾥Tair,业界的Redis,Memcached,Ehcache-配置中⼼:⽤来统⼀管理各个项⽬中所有配置的系统。如阿⾥Nacos、携程Apollo、百度Disconf-分布式事务:事务的参与者、⽀持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。如阿⾥seata、腾讯DTF-任务调度:分布式环境下提供定时、任务编排、分布式跑批等功能的系统。如阿⾥SchedulerX、业界xxl-job、当当elastic-job、有赞TSP-数据库层⽤于⽀持弹性扩容和分库分表的TDDL,数据库连接池Driud,Binlog同步的Canal等。随着云时代的到来,⼤量公司的业务向云上迁移;为了云上客户能够便捷的使⽤稳定⾼效的中间件能⼒,云⼚商开始将⾃⾝沉淀的基础中间件能⼒云化,⽤于⽀撑各个云上客户和⾃⾝业务的快速⽣长。⼆、中间件的开发随着国内软件⾏业的发展,国内互联⽹公司规模越来越⼤,业务越来越复杂,随之使⽤⼤量的中间件来提⾼后台服务性能。由此产⽣了中间件开发和维护⼈员。诚然,在⼩公司,中间件,例如缓存,MQ,RPC等服务,极⼤可能是由业务开发⼈员⾃⼰维护,或者委托第三⽅云平台运维(⽀付⼀些费⽤)。但,如果后台开发超过200⼈,基本就会组建⾃⼰的中间件或者基础架构团队,⽤于维护后台服务器基础架构和中间件。更⼤规模的公司,则由于各种各样的原因(性能,KPI),会⾃⼰开发中间件,简称⾃研。这要求中间件团队需要更多的⼈员。既然需要中间件开发⼈员,那么中间件开发⼈员⼀般从哪⾥招聘呢?招聘的要求是什么?通常,⼀个公司在刚开始组建中间件团队的时候,都会从公司内部挑选精英⼈才,或者挑选对中间件感兴趣的⼈才。这时候,可能你没有相关经验,但你仍然有机会参与到中间件开发中。反之,如果你没有中间件开发经验,想通过招聘的⽅式进⼊中间件⾏业,那么相对⽽⾔,会有些曲折。那么,假设,你想从事中间件开发,但,你没有中间件开发经验,且,你的公司也没有组建中间件团队的打算。该怎么突破?答:跳槽。跳槽到别的公司的中间件团队。这⾥就涉及到了⼀个中间件团队需要哪些技能。因为跳槽肯定就要⾯试,如果你⾯试的是中间件岗位,那么⾃然,就需要准备中间件的相关知识。另外,还有⼀点,在这个分⼯明确的时代,即使是中间件,也有很多种类,我这⾥稍微分⼀下,可能不是很准确。1.服务治理中间件,例如RPC相关中间件,限流熔断,链路追踪,分布式配置中⼼等等。你可以从SpringCloud⾥找到相关的产品。当然国内也有很多优秀的产品。2.存储中间件,例如缓存,MQ等等,如果存储涉及到分布式(通常都会涉及),那么要求相对较⾼。3.各种Proxy,不论是数据库,还是Cache,还是各种存储,通常单机⽆法承载海量数据,⽐较简单的办法就是使⽤Proxy进⾏代理,让应⽤透明的使⽤集群。出于性能考虑,这⾥通常会使⽤性能较⾼的产品,例如goLang,C++等。Java的长处——开发效率,在这个地⽅权重不⼤。4.各种分布式中间件,例如ZK这种,这个我个⼈认为难度是较⼤的。分布式向来是软件开发中⽐较困难的⼀个点。特别是涉及到存储和⼀致性。5.回到之前的话题:⼀个中间件开发者需要哪些素质?1.语⾔基础。从Java程序员的⾓度,基础通常就是:集合,并发,JVM,Netty,IO、NIO(mmap,sendfile)2.计算机基础,由于中间件开发⼈员经常和OS打交道,所以计算机基础也必不可少,例如⽂件系统(IO/磁盘),进程线程,内存管理。3.⽹络基础,搞后台的⼈员,肯定要对⽹络熟悉了,熟悉在Linux下排查⽹络问题,熟悉Epoll原理等。4.分布式相关知识,互联⽹海量数据背景下,分布式知识必不可少,CAP,Paxos,Raft,zab,2pc,3pc,base等等。最好能根据这些理论写出实现代码。5.熟悉开源实现,即使你是业务开发⼈员,你也100%会接触开源项⽬,例如Spring,那么,通常你需要对这种常⽤的开源代码有深刻的理解,不仅知晓其原理,也领会其设计。从⼤的⾓度看,你得看清整个框架的背景,设计和取舍,从⼩的⾓度看,你得看清框架的内部实现细节,有哪些有趣的地⽅(通常这种框架都会进⾏性能优化)。6.了解⾏业风向标,中间件⾏业和业务开发稍有不同,每个中间件的版本升级都会让该领域的开发者们侧⽬(类似iPhone发布会),了解其特性,进⽽了解⾏业趋势,最后成为⾏业引领。好,说完了中间件开发⼈员需要哪些素质,⾃然,如何成为中间件开发⼈员,就不⾔⾃明了。说⽩了,以上6个点,都是硬⾻头。对于已经开始⼯作的⼈来说,需要平时深刻的积累,说的难听⼀点,如果你的业务开发任务很重,你很难搞定上门的这些内容。对于还在上学的同学来说,很爽,你可以⽤学校(不仅仅指⼤学,据我所知的⼤神,通常是初中/⼩学就开始编程,但这不是必须的)⾥⼤把的时间来学习,⼀个个的搞定这些知识点,和社招不同,如果你的知识达到上⾯的⽔平,那么SPoffer应该是随便拿了:)我这⾥重点和那些平时开发任务不重,想搞中间件的同学聊聊。我假设你是⼀个⼯作3年以内的Java开发⼈员,且你可能是培训⽣,半路出家,科班⽣,⼤专⽣,初中⽣,且你不在⼤⼚,通常在⼀个后台开发不超过200⼈的创业公司,title是“Java开发⼯程师”,并且有⼀个程序员的梦想,不想get、set,不想crud,不想html填空,不想和产品同学讨论,也不想和测试同学点点点…(感觉这⾥会得罪⼈=_=||)你可能想跳槽。那么你⼤概需要做以下准备:1.巩固Java基础,集合源码,并发源码,JVM原理,Netty原理源码,IO相关(涉及到零拷贝⽂件存储),这些都是Java基础,通常是必须的。2.分布式原理,最起码知晓理论知识,最好能写⼀个,哪怕参照开源的也⾏。3.源码,SpringMybatisTomcat等等,这些代码通常是你最先接触的,不妨从这⾥开始。RPC中间件相关的,Dubbo,Motan,SOFA,挑⼀个吧,推荐SOFA。4.再熟悉熟悉(熟悉指源码和设计)分布式的相关产品,假设你是Java开发,推荐RocketMQ,Apollo配置中⼼等等中间件,其实都可以,MQ相对复杂。5.操作系统,通常,你在研究上⾯的内容时,会遇到操作系统的疑问,遇到不要绕过,尽量弄明⽩。6.⾃⼰的产品,有就最好了,例如公众号,博客,教学视频,GitHub项⽬等等,总之,是拿得出⼿的东西。7.加⼤⽜好友,了解⾏业风向标。也许你是⼀个矜持的⼈,但从事了这个⾏业,你有必要和⾏业⾥优秀的⼈学习(看看朋友圈就好)。三、和NoSQL之前写了⼀篇关于数据库的基础博客:下⾯来看看NoSQL的含义。关系型数据库建⽴在关系型数据模型的基础上,是借助于集合代数等数学概念和⽅法来处理数据的数据库。现实世界中的各种实体以及实体之间的各种联系均可⽤关系模型来表⽰,市场上占很⼤份额的Oracle、、DB2等都是⾯向关系模型的DBMS。在关系型数据库中,实体以及实体间的联系均由单⼀的结构类型来表⽰,这种逻辑结构是⼀张⼆维表。图1所⽰的学⽣选课系统中,实体和实体间联系在数据库中的逻辑结构可通过图2所⽰。图1:关系型数据库图2:学⽣选课系统数据库逻辑结构关系型数据库以⾏和列的形式存储数据,这⼀系列的⾏和列被称为表,⼀组表组成了数据库。图3所⽰的员⼯信息表就是关系型数据库。图3:员⼯信息表属性说明:⼆维表:也称为关系,它是⼀系列⼆维数组的集合,⽤来代表与存储数据对象之间的关系。它由纵向的列和横向的⾏组成。⾏:也叫元组或记录,在表中是⼀条横向的数据集合,代表⼀个实体。列:也叫字段或属性,在表中是⼀条纵⾏的数据集合。列也定义了表中的。主属性:关系中的某⼀属性组,若它们的值唯⼀地标识⼀个记录,则称该属性组为主属性或主键。主属性可以是⼀个属性,也可以由多个属性共同组成。在图1-5中,学号是学⽣信息表的主属性,但是课程信息表中,学号和课程号共同唯⼀地标识了⼀条记录,所以学号和课程号⼀起组成了课程信息表的主属性。结构化查询语⾔关系型数据库的核⼼是其结构化的查询语⾔(StructuredQueryLanguage,SQL),SQL涵盖了数据的查询、操纵、定义和控制,是⼀个综合的、通⽤的且简单易懂的数据库管理语⾔。同时SQL⼜是⼀种⾼度⾮过程化的语⾔,数据库管理者只需要指出做什么,⽽不需要指出该怎么做即可完成对数据库的管理。SQL可以实现数据库全⽣命周期的所有操作,所以SQL⾃产⽣之⽇起就成了检验关系型数据库管理能⼒的“试⾦⽯”,SQL标准的每⼀次变更和完善都引导着关系型数据库产品的发展⽅向。SQL包含以下四个部分。)DDL包括CREATE、DROP、ALTER等动作。在数据库中使⽤CREATE来创建新表,DROP来删除表,ALTER负责数据库对象的修改。例如,创建学⽣信息表使⽤以下命令:CREATETABLEStuInfo(idint(10)NOTNULL,PRIMARYKEY(id),namevarchar(20),femalebool,classvarchar(20));)DQL负责进⾏数据查询,但是不会对数据本⾝进⾏修改。DQL的语法结构如下:SELECTFROM表名1,表2where查询条件#可以组合and、or、not、=、between、and、in、like等;groupby分组字段having(分组后的过滤条件)orderby排序字段和规则;)DML负责对数据库对象运⾏数据访问⼯作的指令集,以INSERT、UPDATE、DELETE三种指令为核⼼,分别代表插⼊、更新与删除。向表中插⼊数据命令如下:INSERT表名(字段1,字段2,…,字段n,)VALUES(字段1值,字段2值,…,字段n值)where查询条件;)DCL是⼀种可对数据访问权进⾏控制的指令。它可以控制特定⽤户账户对查看表、预存程序、⽤户⾃定义函数等数据库操作的权限,由GRANT和REVOKE两个指令组成。DCL以控制⽤户的访问权限为主,GRANT为授权语句,对应的REVOKE是撤销授权语句。关系型数据库已经发展了数⼗年,其理论知识、相关技术和产品都趋于完善,是⽬前世界上应⽤最⼴泛的数据库系统。容易理解:⼆维表结构⾮常贴近逻辑世界的概念,关系型数据模型相对层次型数据模型和⽹状型数据模型等其他模型来说更容易理解。使⽤⽅便:通⽤的SQL使⽤户操作关系型数据库⾮常⽅便。易于维护:丰富的完整性⼤⼤减少了数据冗余和数据不⼀致的问题。关系型数据库提供对事务的⽀持,能保证系统中事务的正确执⾏,同时提供事务的恢复、回滚、并发控制和死锁问题的解决。随着各类互联⽹业务的发展,关系型数据库难以满⾜对海量数据的处理需求,存在以下不⾜。⾼并发读写能⼒差:⽹站类⽤户的并发性访问⾮常⾼,⽽⼀台数据库的最⼤连接数有限,且硬盘I/O有限,不能满⾜很多⼈同时连接。对海量数据的读写效率低:若表中数据量太⼤,则每次的读写速率都将⾮常缓慢。扩展性差:在⼀般的关系型数据库系统中,通过升级数据库服务器的硬件配置可提⾼数据处理的能⼒,即纵向扩展。但纵向扩展终会达到硬件性能的瓶颈,⽆法应对互联⽹数据爆炸式增长的需求。还有⼀种扩展⽅式是横向扩展,即采⽤多台计算机组成集群,共同完成对数据的存储、管理和处理。这种横向扩展的集群对数据进⾏分散存储和统⼀管理,可满⾜对海量数据的存储和处理的需求。但是由于关系型数据库具有数据模型、完整性约束和事务的强⼀致性等特点,导致其难以实现⾼效率的、易横向扩展的分布式架构。数据是当今世界最有价值的资产之⼀。在时代,⼈们⽣产、收集数据的能⼒⼤⼤提升,但是传统的关系型数据库在可扩展性、数据模型和可⽤性⽅⾯已远远不能满⾜当前的数据处理需求,因此,各种数据库系统应运⽽⽣。NoSQL数据库不像关系型数据库那样都有相同的特点,遵循相同的标准。NoSQL数据库类型多样,可满⾜不同场景的应⽤需求,因此取得了巨⼤的成功。NoSQL数据库基本理念是以牺牲事务机制和强⼀致性机制,来获取更好的分布式部署能⼒和横向扩展能⼒,创造出新的数据模型,使其在不同的应⽤场景下,对特定业务数据具有更强的处理性能。NoSQL数据库最初是为了满⾜互联⽹的业务需求⽽诞⽣的,互联⽹数据具有⼤量化、多样化、快速化等特点。在信息化时代背景下,互联⽹数据增长迅猛,数据集合规模已实现从GB、PB到ZB的飞跃。数据不仅仅是传统的结构化数据,还包含了⼤量的⾮结构化和半结构化数据,关系型数据库⽆法存储此类数据。因此,很多互联⽹公司着⼿研发新型的、⾮关系型的数据库,这类⾮关系型数据库统称为NoSQL数据库,其主要优势如下。互联⽹数据如⽹站⽤户信息、地理位置数据、社交图谱、⽤户产⽣的内容、机器⽇志数据以及传感器数据等,正在快速改变着⼈们的通信、购物、⼴告、娱乐等⽇常⽣活,没有使⽤这些数据的应⽤很快就会被⽤户所遗忘。开发者希望使⽤⾮常灵活的数据库,容纳新的数据类型,并且不会被第三⽅数据提供商的变化所影响。关系型数据库的数据模型定义严格,⽆法快速容纳新的数据类型。例如,若要存储客户的电话号码、姓名、地址、城市等信息,则SQL数据库需要提前知晓要存储的是什么。这对于敏捷开发模式来说⼗分不⽅便,因为每次完成新特性时,通常都需要改变数据库的模式。NoSQL数据库提供的数据模型则能很好地满⾜这种需求,各种应⽤可以通过这种灵活的数据模型存储数据⽽⽆须修改表;或者只需增加更多的列,⽆须进⾏数据的迁移。对企业来说,关系型数据库⼀开始是普遍的选择。然⽽,在使⽤关系型数据库的过程中却遇到了越来越多的问题,原因在于它们是中⼼化的,是纵向扩展⽽不是横向扩展的。这使得它们不适合那些需要简单且动态可伸缩性的应⽤。NoSQL数据库从⼀开始就是分布式、横向扩展的,因此⾮常适合互联⽹应⽤分布式的特性。在互联⽹应⽤中,当数据库服务器⽆法满⾜数据存储和数据访问的需求时,只需要增加多台服务器,将⽤户请求分散到多台服务器上,即可减少单台服务器的性能瓶颈出现的可能性。由于关系型数据库存储的是结构化的数据,所以通常采⽤纵向扩展,即单台服务器要持有整个数据库来确保可靠性与数据的持续可⽤性。这样做的代价是⾮常昂贵的,⽽且扩展也会受到限制。针对这种问题的解决⽅案就是横向扩展,即添加服务器⽽不是扩展单台服务器的处理能⼒。NoSQL数据库通常都⽀持⾃动分⽚,这意味着它们会⾃动地在多台服务器上分发数据,⽽不需要应⽤程序增加额外的操作。NoSQL数据库⽀持⾃动复制。在NoSQL数据库分布式集群中,服务器会⾃动对数据进⾏备份,即将⼀份数据复制存储在多台服务器上。因此,当多个⽤户访问同⼀数据时,可以将⽤户请求分散到多台服务器中。同时,当某台服务器岀现故障时,其他服务器的数据可以提供备份,即NoSQL数据库的分布式集群具有⾼可⽤性与灾备恢复的能⼒。需要通过分布式的集群⽅式来解决存储和访问的问题。分布式系统的核⼼理念是让多台服务器协同⼯作,完成单台服务器⽆法处理的任务,尤其是⾼并发或者⼤数据量的任务。分布式数据库是数据库技术与⽹络技术相结合的产物,它通过⽹络技术将物理上分开的数据库连接在⼀起,进⾏逻辑层⾯上的集中管理。在分布式数据库系统中,⼀个应⽤程序可以对数据库进⾏透明操作,数据库中的数据分别存储在不同的局部数据库中,由不同机器上不同的DBMS进⾏管理,其的体系结构如下图所⽰。分布式数据处理使⽤分⽽治之的办法来解决⼤规模数据管理问题,它处理数据的基本特点如下。在分布式系统中,数据不是存储在⼀个场地上,⽽是存储在计算机⽹络的多个场地上。但逻辑上是⼀个整体,它们被所有⽤户共享,并由⼀个DBMS统⼀管理。⽤户访问数据时⽆须指出数据存放在哪⾥,也不需要知道由分布式系统中的哪台服务器来完成。分布式数据的复制有助于提⾼性能,更易于协调不同⽽⼜冲突的⽤户需求。同时,当某台服务器出现故障时,此服务器上的数据在其他服务器上还有备份,提⾼了系统的可⽤性。这种多副本的⽅式对⽤户来说是透明的,即⽤户不需要知道副本的存在,由系统统⼀管理、协调副本的调⽤。分布式数据处理具有重复的构成,因此消除了单点故障的问题,即系统中⼀个或多个服务器发送故障不会使整个系统瘫痪,从⽽提⾼了系统的可靠性。但是在分布式系统中,事务是并发的,即不同⽤户可能在同⼀时间对同⼀数据源进⾏访问,这就要求系统⽀持分布式的并发控制,保证系统中数据的⼀致。分布式系统可以解决海量数据的存储和访问,但是在分布式环境下,数据库会遇到更为复杂的问题,举例如下。数据在分布式环境下以多副本⽅式进⾏存储,那么,在为⽤户提供数据访问时如何选择⼀个副本,或者⽤户修改了某⼀副本的数据,如何让系统中每个副本都得到更新。如果正在更新系统所有副本信息时,某个服务器由于⽹络或硬、软件功能出现问题导致其发⽣故障。在这种情况下,如何确保故障恢复时,此服务器上的副本与其他副本⼀致。这些问题给分布式数据库管理系统带来了挑战,它们是分布式系统固有的复杂性,但更重要的是对分布数据的管理,控制数据之间的⼀致性以及数据访问的安全性。CAP理论是针对分布式数据库⽽⾔的,它是指在⼀个分布式系统中,⼀致性(Consistency,C)、可⽤性(Availability,A)、分区容错性(PartitionTolerance,P)三者不可兼得。)⼀致性是指“allnodesseethesamedataatthesametime”,即更新操作成功后,所有节点在同⼀时间的数据完全⼀致。⼀致性可以分为客户端和服务端两个不同的视⾓:从客户端⾓度来看,⼀致性主要指多个⽤户并发访问时更新的数据如何被其他⽤户获取的问题;从服务端来看,⼀致性则是⽤户进⾏数据更新时如何将数据复制到整个系统,以保证数据的⼀致。⼀致性是在并发读写时才会出现的问题,因此在理解⼀致性的问题时,⼀定要注意结合考虑并发读写的场景。)可⽤性是指“readsandwritesalwayssucceed”,即⽤户访问数据时,系统是否能在正常响应时间返回结果。好的可⽤性主要是指系统能够很好地为⽤户服务,不出现⽤户操作失败或者访问超时等⽤户体验不好的情况。在通常情况下,可⽤性与分布式数据冗余、负载均衡等有着很⼤的关联。)分区容错性是指“thesystemcontinuestooperatedespitearbitrarymessagelossorfailureofpartofthesystem”,即分布式系统在遇到某节点或⽹络分区故障的时候,仍然能够对外提供满⾜⼀致性和可⽤性的服务。分区容错性和扩展性紧密相关。在分布式应⽤中,可能因为⼀些分布式的原因导致系统⽆法正常运转。分区容错性⾼指在部分节点故障或出现丢包的情况下,集群系统仍然能提供服务,完成数据的访问。分区容错可视为在系统中采⽤多副本策略。CAP理论认为分布式系统只能兼顾其中的两个特性,即出现CA、CP、AP三种情况,如图所⽰。P如果不要求PartitionTolerance,即不允许分区,则强⼀致性和可⽤性是可以保证的。其实分区是始终存在的问题,因此CA的分布式系统更多的是允许分区后各⼦系统依然保持CA。A如果不要求可⽤性,相当于每个请求都需要在各服务器之间强⼀致,⽽分区容错性会导致同步时间⽆限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。C如果要可⽤性⾼并允许分区,则需放弃⼀致性。⼀旦分区发⽣,节点之间可能会失去联系,为了实现⾼可⽤,每个节点只能⽤本地数据提供服务,⽽这样会导致全局数据的不⼀致性。在实践中,可根据实际情况进⾏权衡,或者在软件层⾯提供配置⽅式,由⽤户决定如何选择CAP策略。CAP理论可⽤在不同的层⾯,可以根据CAP原理定制局部的设计策略,例如,在分布式系统中,每个节点⾃⾝的数据是能保证CA的,但在整体上⼜要兼顾AP或CP。ACID是关系型数据库的事务机制需要遵守的原则。事务是⼀个⼀致和可靠计算的基本单元,由作为原⼦单元执⾏的⼀系列数据库操作组成。数据库库⼀般在启动时会提供事务机制,包括事务启动、停⽌、取消或回滚等。关系型数据库⽀持事务的ACID原则,即原⼦性(Atomicity)、⼀致性(Consistency)、隔离性(Isolation)、持久性(Durability),这四种原则保证在事务过程当中数据的正确性,具体描述如下。)⼀个事务的所有系列操作步骤被看成⼀个动作,所有的步骤要么全部完成,要么⼀个也不会完成。如果在事务过程中发⽣错误,则会回滚到事务开始前的状态,将要被改变的数据库记录不会被改变。)⼀致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏,即数据库事务不能破坏关系数据的完整性及业务逻辑上的⼀致性。)主要⽤于实现并发控制,隔离能够确保并发执⾏的事务按顺序⼀个接⼀个地执⾏。通过隔离,⼀个未完成事务不会影响另外⼀个未完成事务。)⼀旦⼀个事务被提交,它应该持久保存,不会因为与其他操作冲突⽽取消这个事务。从事务的四个特性可以看到关系型数据库是要求强⼀致性的,但是这⼀点在数据库中是重点弱化的机制。原因是当数据库保存强⼀致性时,很难保证系统具有横向扩展和可⽤性的优势,因此针对分布式数据存储管理只提供了弱⼀致性的保障,即。BASE理论是针对数据库⽽⾔的,它是对理论中⼀致性(C)和可⽤性(A)进⾏权衡的结果,源于提出者⾃⼰在⼤规模分布式系统上实践的总结。其核⼼思想是⽆法做到强⼀致性,但每个应⽤都可以根据⾃⾝的特点,采⽤适当⽅式达到最终⼀致性。)基本可⽤指分布式系统在出现故障时,系统允许损失部分可⽤性,即保证核⼼功能或者当前最重要功能可⽤。对于⽤户来说,他们当前最关注的功能或者最常⽤的功能的可⽤性将会获得保证,但是其他功能会被削弱。)软状态允许系统数据存在中间状态,但不会影响系统的整体可⽤性,即允许不同节点的副本之间存在暂时的不⼀致情况。最终⼀致性(EventuallyConsistent)最终⼀致性要求系统中数据副本最终能够⼀致,⽽不需要实时保证数据副本⼀致。例如,银⾏系统中的⾮实时转账操作,允许24⼩时内⽤户账户的状态在转账前后是不⼀致的,但24⼩时后账户数据必须正确。最终⼀致性是BASE原理的核⼼,也是NoSQL数据库的主要特点,通过弱化⼀致性,提⾼系统的可伸缩性、可靠性和可⽤性。⽽且对于⼤多数Web应⽤,其实并不需要强⼀致性,因此牺牲⼀致性⽽换取⾼可⽤性,是多数分布式数据库产品的⽅向。最终⼀致性可以分为客户端和服务端两个不同的视⾓。从客户端来看,⼀致性主要指的是多并发访问时更新过的数据如何获取的问题,最终⼀致性有以下5个变种。说明如果进程A通知进程B它已更新了⼀个数据项,那么,进程B的后续访问将返回更新后的值,且⼀次写⼊将保证取代前⼀次写⼊。与进程A⽆因果关系的进程C的访问遵守⼀般的最终⼀致性规则。读⼰之所写(Read-当进程A⾃⼰更新⼀个数据项之后,它总是访问到更新过的值,且不会看到旧值。这是因果⼀致性模型的⼀个特例。这是上⼀个模型的实⽤版本,它把访问存储系统的进程放到会话的上下⽂中。只要会话还存在,系统就保证“读⼰之所写”⼀致性。如果由于某些失败情形令会话终⽌,就要建⽴新的会话,⽽且系统保证不会延续到新的会话。如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值之前的值。系统保证来⾃同⼀个进程的写操作顺序执⾏。单调写⼀致性上述最终⼀致性的不同⽅式可以进⾏组合,例如,单调读⼀致性和“读⼰之所写”⼀致性就可以组合实现。从实践的⾓度来看,这两者的组合读取⾃⼰更新的数据,⼀旦读取到最新的版本,就不会再读取旧版本,对基于此架构上的程序开发来说,会减少很多额外的烦恼。从服务端来看,如何尽快地将更新后的数据分布到整个系统,降低达到最终⼀致性的时间窗⼝,是提⾼系统的可⽤度和⽤户体验度⾮常重要的⽅⾯。分布式数据系统有以下特性:N为数据复制的份数。W为更新数据时需要进⾏写操作的节点数。R为读取数据的时候需要读取的节点数。如果W+R>N,写的节点和读的节点重叠,则是强⼀致性。例如,对于典型的⼀主⼀备同步复制的关系型数据库(N=2,W=2,R=1),则不管读的是主库还是备库的数据,都是⼀致的。如果W+R≤N,则是弱⼀致性。例如,对于⼀主⼀备异步复制的关系型数据库(N=2,W=1,R=1),如果读的是备库,则可能⽆法读取主库已经更新过的数据,所以是弱⼀致性。对于分布式系统,为了保证⾼可⽤性,⼀般设置N≥3。设置不同的N、W、R组合,是在可⽤性和⼀致性之间取⼀个平衡,以适应不同的应⽤场景。如果N=W且R=1,则任何⼀个写节点失效,都会导致写失败,因此可⽤性会降低。但是由于数据分布的N个节点是同步写⼊的,因此可以保证强⼀致性。如果N=R且W=1,则只需要⼀个节点写⼊成功即可,写性能和可⽤性都⽐较⾼。但是读取其他节点的进程可能不能获取更新后的数据,因此是弱⼀致性。在这种情况下,如果W<(N+1)/2,并且写⼊的节点不重叠,则会存在写冲突。NoSQL关系型数据库产品很多,如、Oracle、MicrosoftSQLSever等,但它们的基本模型都是关系型数据模型。并没有统⼀的模型,⽽且是⾮关系型的。常见的NoSQL数据库包括键值数据库、列族数据库、⽂档数据库和图形数据库,其具体分类和特点如表所⽰。应⽤场景数据模型优点缺点键值数据库<key,value>键值对,通过散列表来实现扩展性好,灵活性好,⼤量操作时性能⾼内容缓存,如会话、配置⽂件、参数等;频繁读写、拥有简单数据模型的应⽤数据⽆结构化,通常只被当做字符串或者⼆进制数据,只能通过键来查询值列族以列族式存储,将同数据模型可扩展性强,查找速优点、分布式数据存储与管理应⽤场景功能局限,不⽀持事务的强⼀致性缺点相关产品⼀列数据存在⼀起度快,复杂性低Cassandra⽂档数据库、<key,value>value灵活,可以根据value构建索引缺乏统⼀查询语法图形数据库社交⽹络、推荐系统,专注构建关系图谱图结构⽀持复杂的图形算法复杂性⾼,只能⽀持⼀定的数据规模NoSQL数据库并没有⼀个统⼀的架构,两种不同的NoSQL数据库之间的差异程度,远远超过两种关系型数据库之间的不同。可以说,NoSQL数据库各有所长,⼀个优秀的NoSQL数据库必然特别适⽤于某些场合或者某些应⽤,在这些场合中会远远胜过关系型数据库和其他的NoSQL数据库。常见的NoSQL数据库分为以下⼏种。这⼀类数据库主要会使⽤到⼀个散列表,这个表中有⼀个特定的键和⼀个指针指向特定的数据。键值模型对于IT系统来说,其优势在于简单、易部署。键值数据库可以按照键对数据进⾏定位,还可以通过对键进⾏排序和分区,以实现更快速的数据定位。列族数据库通常⽤来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列,如图所⽰。此列族数据库表中由两⾏组成,每⼀⾏都有关键字RowKey,每⼀⾏由多个列族组成,即Column-Family-1和Column-Family-2,⽽每个列族由多个列组成。⽂档数据库的灵感来⾃LotusNotes办公软件,它与键值数据库类似。该类型的数据模型是版本化的⽂档,⽂档以特定的格式存储,如JSON。⽂档数据库可以看作键值数据库的升级版,允许之间嵌套键值,如图所⽰。⽂档数据库⽐键值数据库的查询效率更⾼,因为⽂档数据库不仅可以根据键创建索引,同时还可以根据⽂档内容创建索引。图形数据库来源于图论中的拓扑学,以节点、边及节点之间的关系来存储复杂⽹络中的数据,如图所⽰。这种拓扑结构类似E-R图,但在图形模式中,关系和节点本⾝就是数据,⽽在E-R图中,关系描述的是⼀种结构。内存数据库主要是把磁盘的数据加载到内存中进⾏相应操作。与直接读取磁盘数据相⽐,内存的数据读取速度要⾼出⼏个数量级,因此,将数据保存在内存中能够极⼤地提⾼应⽤的性能。内存数据库改变了磁盘数据管理的传统⽅式,基于全部数据都在内存中的特点重新设计了体系结构,并且在数据缓存、快速算法、并⾏操作⽅⾯也进⾏了相应的升级,因此,其数据处理速度⼀般⽐传统数据库的数据处理速度快⼏⼗倍。内存数据库的最⼤特点是其应⽤数据常驻内存中,即活动事务只与实时内存数据库的内存进⾏数据交流。常见的内存数据库有Memcached、、SQLite、MicrosoftSQLServerCompact等。Memcached是LiveJournal旗下DangaInteractive公司的布拉德·菲茨帕特⾥克(BradFitzpatric)开发的⼀款,现在已被应⽤于Facebook、LiveJournal等公司⽤于提⾼Web服务质量。⽬前这款软件流⾏于全球各地,经常被⽤来建⽴缓存项⽬,并以此分担来⾃传统数据库的并发负载压⼒。Memcached可以轻松应对⼤量同时出现的数据请求,⽽且它拥有独特的⽹络结构,在⼯作机制⽅⾯,它还可以在内存中单独开辟新的空间,建⽴HashTable,并对HashTable进⾏有效的管理。我们有时会见到Memcache和Memcached两种不同的说法,为什么会有两种名称?其实Memcache是这个项⽬的名称,⽽Memcached是它服务器端的主程序⽂件名。⼀个是项⽬名称,另⼀个是主程序⽂件名。为什么要使⽤Memcached由于⽹站的⾼并发读写和对海量数据的处理需求,传统的关系型数据库开始出现瓶颈。关系型数据库本⾝就是个庞然⼤物,处理过程⾮常耗时(如解析SQL语句、事务处理等)。如果对关系型数据库进⾏⾼并发读写(每秒上万次的访问),数据库系统是⽆法承受的。对于⼤型的SNS⽹站(如Twitter、新浪微博),每天有上千万条的数据产⽣。对关系型数据库⽽⾔,如果在⼀个有上亿条数据的数据表中查找某条记录,效率将⾮常低。使⽤Memcached就能很好地解决以上问题。多数Web应⽤都将数据保存到关系型数据库中(如),Web服务器从中读取数据并在浏览器中显⽰。但随着数据量的增⼤,访问的集中,关系型数据库的负担就会加重,岀现响应缓慢、⽹站打开延迟时间长等问题。因此,使⽤Memcached的主要⽬的是通过⾃⾝内存中缓存关系型数据库的查询结果,减少数据库⾃⾝被访问的次数,以提⾼动态Web应⽤的速度,增强⽹站架构的并发能⼒和可扩展性。通过在事先规划好的系统内存空间中临时缓存数据库中的各类数据,以达到减少前端业务服务对关系型数据库的直接⾼并发访问,从⽽达到提升⼤规模⽹站集群中动态服务的并发访问能⼒。Web服务器读取数据时先读Memcached服务器,若Memcached没有所需的数据,则向数据库请求数据,然后Web再把请求到的数据发送到Memcached,如下图所⽰。是⼀个开源的、⾼性能的、键值对。它通过提供多种键值数据类型来满⾜不同场景下的存储需求,并借助许多⾼层级的接⼝使其可以胜任如缓存、队列系统等不同的⾓⾊。本⼩节将介绍Redis的历史和特性,以使读者能够快速地对Redis有⼀个全⾯的了解。2008年,意⼤利的⼀家创业公司Merzia推出了⼀款基于的⽹站实时统计系统——LLOOGG,然⽽没过多久,该公司的创始⼈萨尔⽡托·桑菲利普(SalvatoreSanfilippo)便对这个系统的性能感到失望,于是他决定亲⾃为LLOOGG量⾝定做⼀个数据库,并于2009年开发完成,这个数据库就是Redis。不过萨尔⽡托并不满⾜只将Redis⽤于LLOOGG这⼀款产品,⽽是希望让更多的⼈使⽤它,于是萨尔⽡托将Redis开源发布,并开始和Redis的另⼀名主要的代码贡献者⽪特·诺德胡斯(PieterNoordhuis)⼀起继续着Redis的开发,直到今天。萨尔⽡托⾃⼰也没有想到,在短短的⼏年时间内,Redis就拥有了庞⼤的⽤户群体。HackedNews在2012年发布了⼀份数据库的使⽤情况调查,结果显⽰有近12%的公司在使⽤Redis。国内如新浪微博和知乎,国外如GitHub、StackOverflow、Flickr、暴雪和Instagram,都是Redis的⽤户。现在使⽤Redis的⽤户越来越多,⼤多数的互联⽹公司都使⽤Redis作为公共缓存。VMware公司从2010年开始赞助Redis的开发,萨尔⽡托和⽪特也分别于同年的3⽉和5⽉加⼊VMware,全职开发Redis。有过脚本语⾔编程经验的读者对字典(或称映射、关联数组)⼀定很熟悉,如在代码dict[“key”]=“value”中,“diet”是⼀个字典结构变量,字符串“key”是键名,⽽“value”是键值,在字典中可以获取或设置键名对应的键值,也可以删除⼀个键。Redis是RemoteDictionaryServer(远程字典服务器)的缩写,它以字典结构存储数据,并允许其他应⽤通过TCP读写字典中的内容。同⼤多数脚本语⾔中的字典⼀样,Redis字典中的键值除了可以是字符串,还可以是其他数据类型。到⽬前为⽌,Redis⽀持的键值数据类型有:字符串类型、散列类型、列表类型、集合类型和有序集合类型。这种字典形式的存储结构与常见的MySQL等关系数据库的⼆维表形式的存储结构有很⼤的差异。举个例⼦,在程序中使⽤post变量存储了⼀篇⽂章的数据(包括标题、正⽂、阅读量和标签),如下所⽰:post["tags"]=["PHP","Ruby","Node.js"]现在希望将这篇⽂章的数据存储在数据库中,并且要求可以通过标签检索岀⽂章。如果使⽤关系数据库存储,⼀般会将其中的标题、正⽂和阅读量存储在⼀个表中,⽽将标签存储在另⼀个表中,然后使⽤第三个表连接⽂章和标签表。需要查询时还需要连接三个表,不是很直观。⽽Redis字典结构的存储⽅式和对多种键值数据类型的⽀持使得开发者可以将程序中的数据直接映射到Redis中,数据在Redis中的存储形式和其在程序中的存储⽅式⾮常相似。使⽤Redis的另⼀个优势是其对不同的数据类型提供了⾮常⽅便的操作⽅式,如使⽤集合类型存储⽂章标签,Redis可以对标签进⾏如交集、并集等集合运算操作。Redis数据库中的所有数据都存储在内存中。由于内存的读写速度远⾼于硬盘,因此Redis在性能上与其他基于硬盘存储的数据库相⽐有⾮常明显的优势。在⼀台普通的笔记本电脑上,Redis可以在⼀秒内读写超过10万个键值。将数据存储在内存中也有问题,例如,程序退出后内存中的数据会丢失。不过Redis提供了对持久化的⽀持,即可以将内存中的数据异步写⼊硬盘中,同时不影响其继续提供服务。Redis虽然是作为数据库开发的,但由于其提供了丰富的功能,越来越多的⼈将其⽤作缓存、队列系统等。Redis可谓是名副其实的多⾯⼿。Redis可以为每个键设置⽣存时间(TimeToLive,TTL),⽣存时间到期后键会⾃动被删除。这⼀功能配合出⾊的性能让Redis可以作为缓存系统来使⽤,⽽且由于Redis⽀持持久化和丰富的数据类型,使其成为另⼀个⾮常流⾏的缓存系统Memcached的有⼒竞争者。讨论Redis和Memcached的优劣⼀直是⼀个热门的话题。由于Redis是单线程模型,⽽Memcached⽀持多线程,所以在多核服务器上后者的性能更⾼⼀些。然⽽,前⾯已经介绍过,Redis的性能已经⾜够优异,在绝⼤部分场合下其性能都不会成为瓶颈。所以在使⽤时更应该关⼼的是⼆者在功能上的区别,如果需要⽤到⾼级的数据类型或持久化等功能,Redis将会是Memcached很好的替代品。作为缓存系统,Redis还可以限定数据占⽤的最⼤内存空间,在数据达到空间限制后可以按照⼀定的规则⾃动淘汰不需要的键。除此之外,Redis的列表类型键可以⽤来实现队列,⽀持阻塞式读取,并且可以很容易地实现⼀个⾼性能的优先级队列。同时,在更⾼层⾯上,Redis还⽀持“发布/订阅”的消息模式,⽤户可以基于此构建聊天室等系统。如果⼀个⼯具使⽤起来太复杂,即使它的功能再丰富也很难吸引⼈。Redis直观的存储结构使其通过程序与Redis交互⼗分简单。在Redis中使⽤命令来读写数据,命令语句之于Redis就相当于SQL之于关系数据库。例如,在关系数据库中要获取posts表内id为1的记录的title字段的值,可以使⽤如下SQL语句实现:SELECTtitleFROMpostsWHEREid=1LIMIT1相对应的,在Redis中要读取键名为post:1的散列类型键的title字段的值,可以使⽤如下命令语句实现:HGETpost:1title其中,HGET就是⼀个命令。Redis提供了100多个命令,但是常⽤的只有⼗⼏个,并且每个命令都很容易记住。Redis提供了⼏⼗种不同编程语⾔的客户端库,这些库都封装了Redis的命令,这样在程序中与Redis进⾏交互变得很容易。有些库还提供了可以将编程语⾔中的数据类型直接以相应的形式存储到Redis中(如将数组直接以列表类型存⼊Redis)的简单⽅法,使⽤起来⾮常⽅便。Redis使⽤C语⾔开发,代码量只有3万多⾏。这降低了⽤户通过修改Redis源代码来使之更适合⾃⼰项⽬需要的门槛。对于希望“榨⼲”数据库性能的开发者⽽⾔,这⽆疑具有很⼤的吸引⼒。Redis是开源的,有将近100名开发者为Redis贡献了代码。良好的开发氛围和严谨的版本发布机制使得Redis的稳定版本的性能⾮常可靠,如此多的公司选择使⽤Redis也可以印证这⼀点。与Memcached与Redis的⽐较见下表。数据库MemcachedRedisCPU⽀持多核单核内存利⽤率持久性数据结构简单⼯作环境Linux/WindowsLinux⾼⽆低(压缩⽐Memcached⾼)有(硬盘存储,主从同步)复杂四、分布式系统分布式系统是由⼀组通过⽹络进⾏通信、为了完成共同的任务⽽协调⼯作的计算机节点组成的系统。分布式系统的出现是为了⽤廉价的、普通的机器完成单个计算机⽆法完成的计算、存储任务。其⽬的是利⽤更多的机器,处理更多的数据。⾸先需要明确的是,只有当单个节点的处理能⼒⽆法满⾜⽇益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使⽤更好的CPU)⾼昂到得不偿失的时候,应⽤程序也不能进⼀步优化的时候,我们才需要考虑分布式系统。因为,分布式系统要解决的问题本⾝就是和单机系统⼀样的,⽽由于分布式系统多节点、通过⽹络通信的拓扑结构,会引⼊很多单机系统没有的问题,为了解决这些问题⼜会引⼊更多的机制、协议,带来更多的问题。。。在很多⽂章中,主要讲分布式系统分为分布式计算(computation)与分布式存储(storage)。计算与存储是相辅相成的,计算需要数据,要么来⾃实时数据(流数据),要么来⾃存储的数据;⽽计算的结果也是需要存储的。在操作系统中,对计算与存储有⾮常详尽的讨论,分布式系统只不过将这些理论推⼴到多个节点罢了。那么分布式系统怎么将任务分发到这些计算机节点呢,很简单的思想,分⽽治之,即分⽚(partition)。对于计算,那么就是对计算任务进⾏切换,每个节点算⼀些,最终汇总就⾏了,这就是MapReduce的思想;对于存储,更好理解⼀下,每个节点存⼀部分数据就⾏了。当数据规模变⼤的时候,Partition是唯⼀的选择,同时也会带来⼀些好处:(1)提升性能和并发,操作被分发到不同的分⽚,相互独⽴(2)提升系统的可⽤性,即使部分分⽚不能⽤,其他分⽚不会受到影响理想的情况下,有分⽚就⾏了,但事实的情况却不⼤理想。原因在于,分布式系统中有⼤量的节点,且通过⽹络通信。单个节点的故障(进程crash、断电、磁盘损坏)是个⼩概率事件,但整个系统的故障率会随节点的增加⽽指数级增加,⽹络通信也可能出现断⽹、⾼延迟的情况。在这种⼀定会出现的“异常”情况下,分布式系统还是需要继续稳定的对外提供服务,即需要较强的容错性。最简单的办法,就是冗余或者复制集(Replication),即多个节点负责同⼀个任务,最为常见的就是分布式存储中,多个节点复杂存储同⼀份数据,以此增强可⽤性与可靠性。同时,Replication也会带来性能的提升,⽐如数据的locality可以减少⽤户的等待时间。下⾯这种来⾃的图形象⽣动说明了Partition与Replication是如何协作的。Partition和Replication是解决分布式系统问题的⼀记组合拳,很多具体的问题都可以⽤这个思路去解决。但这并不是银弹,往往是为了解决⼀个问题,会引⼊更多的问题,⽐如为了可⽤性与可靠性保证,引⽤了冗余(复制集)。有了冗余,各个副本间的⼀致性问题就变得很头疼,⼀致性在系统的⾓度和⽤户的⾓度⼜有不同的等级划分。如果要保证强⼀致性,那么会影响可⽤性与性能,在⼀些应⽤(⽐如电商、搜索)是难以接受的。如果是最终⼀致性,那么就需要处理数据冲突的情况。CAP、FLP这些理论告诉我们,在分布式系统中,没有最佳的选择,都是需要权衡,做出最合适的选择。分布式系统挑战分布式系统需要⼤量机器协作,⾯临诸多的挑战:第⼀,异构的机器与⽹络:分布式系统中的机器,配置不⼀样,其上运⾏的服务也可能由不同的语⾔、架构实现,因此处理能⼒也不⼀样;节点间通过⽹络连接,⽽不同⽹络运营商提供的⽹络的带宽、延时、丢包率⼜不⼀样。怎么保证⼤家齐头并进,共同完成⽬标,这四个不⼩的挑战。第⼆,普遍的节点故障:虽然单个节点的故障概率较低,但节点数⽬达到⼀定规模,出故障的概率就变⾼了。分布式系统需要保证故障发⽣的时候,系统仍然是可⽤的,这就需要监控节点的状态,在节点故障的情况下将该节点负责的计算、存储任务转移到其他节点第三,不可靠的⽹络:节点间通过⽹络通信,⽽⽹络是不可靠的。可能的⽹络问题包括:⽹络分割、延时、丢包、乱序。相⽐单机过程调⽤,⽹络通信最让⼈头疼的是超时:节点A向节点B发出请求,在约定的时间内没有收到节点B的响应,那么B是否处理了请求,这个是不确定的,这个不确定会带来诸多问题,最简单的,是否要重试请求,节点B会不会多次处理同⼀个请求。总⽽⾔之,分布式的挑战来⾃不确定性,不确定计算机什么时候crash、断电,不确定磁盘什么时候损坏,不确定每次⽹络通信要延迟多久,也不确定通信对端是否处理了发送的消息。⽽分布式的规模放⼤了这个不确定性,不确定性是令⼈讨厌的,所以有诸多的分布式理论、协议来保证在这种不确定性的情况下,系统还能继续正常⼯作。⽽且,很多在实际系统中出现的问题,来源于设计时的盲⽬乐观,觉得这个、那个应该不会出问题。很有意思,介绍了分布式系统新⼿可能的错误的假设:Thenetworkissecure.Topologydoesn’tchange.Thereisoneadministrator.Transportcostiszero.Thenetworkishomogeneous.刘杰在《分布式系统原理介绍》中指出,处理这些异常的最佳原则是:在设计、推导、验证分布式系统的协议、流程时,最重要的⼯作之⼀就是思考在执⾏流程的每个步骤时⼀旦发⽣各种异常的情况下系统的处理⽅式及造成的影响。Adistributedsystemisacollectionofindependentcomputersthatappearstoitsusersasasinglecoherentsystem.可扩展性:分布式系统的根本⽬标就是为了处理单个计算机⽆法处理的任务,当任务增加的时候,分布式系统的处理能⼒需要随之增加。简单来说,要⽐较⽅便的通过增加机器来应对数据量的增长,同时,当任务规模缩减的时候,可以撤掉⼀些多余的机器,达到动态伸缩的效果可⽤性与可靠性:⼀般来说,分布式系统是需要长时间甚⾄7*24⼩时提供服务的。可⽤性是指系统在各种情况对外提供服务的能⼒,简单来说,可以通过不可⽤时间与正常服务时间的必知来衡量;⽽可靠性⽽是指计算结果正确、存储的数据不丢失。⾼性能:不管是单机还是分布式系统,⼤家都⾮常关注性能。不同的系统对性能的衡量指标是不同的,最常见的:⾼并发,单位时间内处理的任务越多越好;低延迟:每个任务的平均时间越少越好。这个其实跟操作系统CPU的调度策略很像⼀致性:分布式系统为了提⾼可⽤性可靠性,⼀般会引⼊冗余(复制集)。那么如何保证这些节点上的状态⼀致,这就是分布式系统不得不⾯对的⼀致性问题。⼀致性有很多等级,⼀致性越强,对⽤户越友好,但会制约系统的可⽤性;⼀致性等级越低,⽤户就需要兼容数据不⼀致的情况,但系统的可⽤性、并发性很⾼很多。假设这是⼀个对外提供服务的⼤型分布式系统,⽤户连接到系统,做⼀些操作,产⽣⼀些需要存储的数据,那么在这个过程中,会遇到哪些组件、理论与协议呢⽤户使⽤Web、APP、SDK,通过HTTP、TCP连接到系统。在分布式系统中,为了⾼并发、⾼可⽤,⼀般都是多个节点提供相同的服务。那么,第⼀个问题就是具体选择哪个节点来提供服务,这个就是负载均衡(loadbalance)。负载均衡的思想很简单,但使⽤⾮常⼴泛,在分布式系统、⼤型⽹站的⽅⽅⾯⾯都有使⽤,或者说,只要涉及到多个节点提供同质的服务,就需要负载均衡。通过负载均衡找到⼀个节点,接下来就是真正处理⽤户的请求,请求有可能简单,也有可能很复杂。简单的请求,⽐如读取数据,那么很可能是有缓存的,即分布式缓存,如果缓存没有命中,那么需要去数据库拉取数据。对于复杂的请求,可能会调⽤到系统中其他的服务。承上,假设服务A需要调⽤服务B的服务,⾸先两个节点需要通信,⽹络通信都是建⽴在TCP/IP协议的基础上,但是,每个应⽤都⼿写socket是⼀件冗杂、低效的事情,因此需要应⽤层的封装,因此有了HTTP、FTP等各种应⽤层协议。当系统愈加复杂,提供⼤量的http接⼝也是⼀件困难的事情。因此,有了更进⼀步的抽象,那就是RPC(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论