- 前述
参加infoq软件大会,最大的感触就是,互联网行业的技术发展日新月异;由市场痛点、用户痛点、开发痛点所驱动的技术变革更是遍地开花、新的技术新的思维也是层出不穷;大会中频频提到的高扩展高可用架构、新兴前端(React.js、Flux、GraphQL、Relay、Immutability、Webpack、Babel)、大数据处理(Spark、Hadoop、kafka、Storm、ELK(ElasticSearchLogstashKibana))、云计算(SaaS、PaaS、IaaS、Openstack)、容器应用(Docker、Mesos、Marathon、kubernetes)等各种技术,都代表了当今互联网行业的发展趋势。通过下面几部分,对各技术点做下梳理。
- 系统优化篇
环境驱动技术,随着互联网行业的发展、业务增长、流量增长是不可避免的;当这种量爆发一定程度,系统的瓶颈突出、系统优化随之产生。
可以借助商用Jprofiler、YourKit、大众点评开源CAT及淘宝开源TProfiler等性能监控工具来分析代码层的运行状况,得到对象创建排行和Java代码执行次数、执行时间排行、执行Url路由、内存使用、cpu消耗等性能指标;从而做出具有针对性的优化。
以淘宝为案例,系统优化大致分三个层面:
- 系统代码层面的优化
- 压缩模板大小
如果能大幅减小模板和HTML的大小,会给吞吐量带来很大提升。最简单的减小模板的方法,就是删除空行和多余空格、长url压缩、url别名;重复渲染的数据可以通过前端代码去做,这种业务去重也能带来很好的优化;
- 模板引擎优化
Velocity模板渲染是最大的模块瓶颈,velocity是解释型语言、执行中还有大量反射,性能较差;淘宝基于velocity开发了语法兼容的sketch框架,将Velocity模板编译成Java类执行,减少了反射调用,内部用字节存储页面,节约了从渲染到输出的两次编码转换。
- class.forname热点
在大并发时,class.forname会导致线程block;可以增加cache代替class.forname。
- 其他
1)能够预处理的决不动态生成;
2)尽量使用简单类型作为HashMap的key;
3)Web.xml配置版本信息减少启动时annotation的扫描时间;
4)Logger创建没有使用static修饰导致线程阻塞;
5)少用Thread.getStackTrace();
6)正则运算尽量cache;
7)Java代码里,private修饰符比不修饰或其他修饰要更快;
8)不可变常量定义加final修饰;
9)StringBuilder代替字符串“+”拼接;
10)优化自定义hasCode()方法和equals()方法;
11)使用原始类型和栈;
- 架构优化
- 数据的动静分离
系统的静态化是读系统性能优化的终极必杀器;
静态化的几个原则:
1)让用户的请求尽量少的经过java应用服务器;
2)让静态数据放在离用户最近的地方;
3)让动态数据尽可能的小;
上图为淘宝优化后的架构图,图中可以看出无论是pc端还是无线端先请求的都是离用户最近的CDN,通过CDN拿到请求页的静态页面及资源,数据的动态部分通过客户端发送请求到服务器,服务器先经过统一Cache过滤掉部分的缓存动态数据,剩余的动态数据则通过下层的动态系统去获取;经过这一动态分离,真正到达应用服务器的动态数据流量已经很小了。
通过上述的动静分离,像商品的详情这一功能,可每天支持30+亿的PV,峰值100w+的QPS;
- 读写的分层校验
看上图这个“双十一”常用的秒杀抢购页面,整个页面是cache用户浏览器,如果强制刷新整个页面,也会请求道CDN,而实际有效的动态请求也只是“刷新抢宝”按钮;
当到了抢购时间,不是立即点击“秒杀”,而是有一个验证码的输入方式,如上图所示;这样做的好处是,既可以防止“自动秒杀器”又可以避免瞬间的并发请求流量峰值。
读写数据的分层校验原则:
1)先做数据的动静分离;
2)将99%的数据缓存在客户端;
3)将动态请求的读数据cache在web端;
4)对读数据不做强一致校验;
5)对写数据进行基于时间的合理分片;
6)对写请求做限流保护;
7)对写数据进行强一致校验;
8)先加载主要数据,后异步加载次要数据;
- 基础设施优化
1)用户访问链路
通过分析访问链路请求响应时间,优化缩短中间的管道处理过程;
如pc端最重要的是优化首屏的加载;
而无线端更多的是优化中间的处理管道,由于无线端的网络、硬件复杂性在同等条件下比pc端要慢很多;可将无线端的多次请求合并一个请求,可控制无线端的数据量大小;
通过CDN和统一Cache再辅助一些动态加速技术,提升用户访问链路的响应;
2)域名的收敛
3)DNS本地cache;
4)SPDY长连;
5)图片本地cache;
6)合理的预加载机制;
7)使用更快的网络传输通道如光纤、更优化的网络拓扑结构;
8)其他的如,软件的升级、JVM的调优、二方包优化、硬件设施如cpu、内存的升级等;
- 系统架构篇
- 淘宝前期技术
随着公司的发展、业务的暴增,以前认为很好的架构已成为拖累业务发展的绊脚石;如何设计出高可用、高稳定、高扩展的系统架构来适应环境的需求呢?还是以淘宝技术作为入口来探讨下:
上图为淘宝早期的技术架构,在当时的环境来说,这个架构也挺好的,分应用、分缓存、分数据库来支撑业务的发展;随着业务量指数级的增长,无论是数据还是业务系统都在之前的基础上翻倍;从而也暴露出一些瓶颈问题。
- 瓶颈问题
1)业务系统的数量增长很快,项目团队协同代价很高;人员更新快、源代码膨胀;
2)数据孤岛;数据库经常被不明sql查挂,同类数据格式不统一;
3)数据库能力达到上限,cpu90%以上,连接数不够用;
4)维护人员多,数据无法共享,数据库压力过大,单点系统风险增加;
- 淘宝3.0
面对上述问题,淘宝作出了技术变革,退出了淘宝3.0,架构图如下:
上图可以看出,淘宝所做的一些改变:
- 服务化(SOA)
将系统进行专业化分工,组建像用户中心、交易中心、评价中心这类服务模块;
系统由服务单元组成、数据共享、服务能力开放;
这一改进使业务支撑更敏捷、无数据孤岛、有利于数据分析和挖掘;
- 去中心化
如上图,整个系统及数据库无单点、系统中所有角色皆可单独扩缩、故障影响小;
这一改进使应用更稳定、扩展性更好;
- 异步化、最终一致
通过消息中间件使流程异步化、去锁、并行,并保证流程最终的一致性;
这一改进使得系统解耦、降低延迟;
组织结构支持,通过服务中心团队、中间件团队、垂直产品团队来维护整个架构;
下图是淘宝所用的一些开源或自研的软件:
其中像dubbo是阿里开源的分布式服务框架,支持多种rpc协议,当当网在其基础上推出dubbox做了很多功能扩展像rest支持等。
- 新兴前端篇
- React.js
React究竟是什么?Facebook把它简单低调地定义成一个“用来构建UI的JavaScript库”。但是React所基于的几个核心概念使它与那些传统的js库迥然不同。React的一些设计原则:
1) 组件和基于组件的设计流程;
2) 单向数据流动;
3) 虚拟DOM取代物理DOM作为操作对象;
4) 用JSX语法取代HTML模板,在JavaScript里声明式地描述UI。
这几条简单的原则放在一起带来了大量的好处:
1) 前端和后端都能够从React组件渲染页面,完全解决了SEO长期困扰JavaScript单页应用的问题;
2) 我们可以简单直接地写前端测试而完全忘掉DOM依赖;
3) 组件的封装方式和单向数据流动能够极大地简化前端架构的理解难度。
下图为一个简单的React例子
这段代码发生在服务器端!是的,同样的 HelloMessage,我们不仅可以让React在前端渲染到页面,同样可以在后端直接渲染成HTML字符串,然后把它返回给前端。
- React Native
React Native是可以替代H5在Android、IOS上开发跨平台应用的解决方案;再加上React web,可以实现一套React跨pc端、无线端,真正实现一次开发多处运行。这也是React一经推出,获得业界广泛关注的原因。
- Flux
React定义自己为MVC中的View;对于M和C,Facebook提出了Flux的概念。Flux是一个专门为React设计的应用程序架构:应用程序由Dispatcher、Store和View组成。Flux的核心是如下图所示的单向数据流动。
应用程序中的任何一次数据变化都作为Action发起,经过Dispatcher分发出去,被相关的Store接收到并整合,然后作为props和state提供给View(React组件)。当用户在View上做了任何与数据相关的交互,View会发起新的Action,开启一次新的数据变化周期。这种单向性使Flux在高层次上比传统MVC架构和以Angular和Knockout为代表的双向数据绑定容易理解得多,大大简化了开发者的思考和Debug过程。
- GraphQL
现在主流的调用服务方式是RESTful API,然而在实践中,我们发现RESTful在一些真实生产环境的需求下不是很适用。往往我们需要构建自定义endpoint,而这违背了RESTful的设计理念。举个例子,我们想要显示论坛帖子、作者和对应的留言。分别要发出三个不同的请求。第二个请求依赖第一个请求结果返回的user_id,前端需要写代码协调请求之间的依赖。分别发出三个不同请求在移动端这种网络不稳定的环境下效果很不理想。
来自Facebook的GraphQL是目前最接近完美的解决方法。后端工程师只需要定义可以被查询的Type System,前端工程师就可以使用GraphQL自定义查询。GraphQL查询语句只需要形容需要返回的数据形状,GraphQL服务器就会返回正确的JSON格式。
- Relay
Relay是Facebook提出的在React上应用GraphQL的方案。React的基础单位是组件(Component),构建大型应用就是组合和嵌套组件。以组件为单位的设计模式是目前社区里最认可的,这也是前端世界的趋势之一。每个组件需要的数据也应该在组件内部定义。Relay让组件可以自定义其所需要GraphQL数据格式,在组件实例化的时候再去GraphQL服务器获取数据。Relay也会自动构建嵌套组件的GraphQL查询,这样多个嵌套的组件只需要发一次请求。
- Immutability
React社区接受了很多函数式编程的想法,其中受Clojure影响很深。对Immutable数据的使用就是来自Clojure社区。当年Om,这个用ClojureScript写的React wrapper在速度上居然完虐原生JavaScript版本的React。这让整个社区都震惊了。其中一个原因就是ClojureScript使用了Immutable数据。React社区里也冒出了Immutable.js,这让JavaScript里也能使用Immutable数据,完美弥补了JavaScript在负责数据对象比较的先天性不足。Immutable.js也成为了构建大型React应用的必备。甚至有在讨论是否把Immutable.js直接纳入JavaScript语言中。我们认为小型应用不会遇到虚拟DOM的性能瓶颈,引入Immutable.js只会让数据操作很累赘。
- Webpack
在React里,由于需要用到JSX,使用Webpack或Browserify这类工具编译代码已经渐渐成为前端工程师工作流程的一部分。Webpack是一款强大的前端模块管理和打包工具。
- Babel
ECMAScript 6(ES6)规范在今年四月刚敲定,React社区基本全面拥抱ES6。但目前还有很多浏览器不支持ES6。使用像Webpack这样的工具编译代码使得我们可以在开发时使用ES6(或者更新版本),在上线前编译成ES5。编译工具中最引人注意的是Babel。前身为ES6to5,Babel是目前社区最火的ES6编译到ES5的代码工具。
- 大数据处理篇
- Hadoop
Hadoop是Appach的一个用java语言实现开源软件框架,实现在大量计算机组成的集群中对海量数据进行分布式计算。Hadoop框架中最核心设计就是:HDFS和MapReduce.HDFS提供了海量数据的存储,MapReduce提供了对数据的计算。
Hadoop的集群主要由 NameNode,DataNode,Secondary NameNode,JobTracker,TaskTracker组成.如下图所示:
Hadoop的局限和不足
1)抽象层次低,需要手工编写代码来完成,使用上难以上手。
2)只提供两个操作,Map和Reduce,表达力欠缺。
3)一个Job只有Map和Reduce两个阶段(Phase),复杂的计算需要大量的Job完成,Job之间的依赖关系是由开发者自己管理的;
4)处理逻辑隐藏在代码细节中,没有整体逻辑;
5)中间结果也放在HDFS文件系统中;
6)ReduceTask需要等待所有MapTask都完成后才可以开始;
7)时延高,只适用Batch数据处理,对于交互式数据处理,实时数据处理的支持不够;
8)对于迭代式数据处理性能比较差;
- Spark
针对上述hadoop的缺陷,推出了Spark。
1) Spark 是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些有用的不同之处使 Spark 在某些工作负载方面表现得更加优越,换句话说,Spark 启用了内存分布数据集,除了能够提供交互式查询外,它还可以优化迭代工作负载。
2)Hadoop/MapReduce和Spark最适合的都是做离线型的数据分析,但Hadoop特别适合是单次分析的数据量“很大”的情景,而Spark则适用于数据量不是很大的情景。这儿所说的“很大”,是相对于整个集群中的内存容量而言的,因为Spark是需要将数据HOLD在内存中的。一般的,1TB以下的数据量都不能算很大,而10TB以上的数据量都是算“很大”的。比如说,20个节点的一个集群(这样的集群规模在大数据领域算是很小的了),每个节点64GB内存(不算很小,但也不能算大),共计1.28TB。让这样规模的一个集群把500GB左右的数据HOLD在内存中还是很轻松的。这时候,用Spark的执行速度都会比Hadoop快,毕竟在MapReduce过程中,诸如spill等这些操作都是需要写磁盘的。
- Storm
- Storm是由BackType开发的实时处理系统,是一个分布式的、容错的实时计算系统;
- 由Twitter开源。
3)在Storm中,先要设计一个用于实时计算的图状结构,我们称之为拓扑(topology)。这个拓扑将会被提交给集群,由集群中的主控节点(master node)分发代码,将任务分配给工作节点(worker node)执行。一个拓扑中包括spout和bolt两种角色,其中spout发送消息,负责将数据流以tuple元组的形式发送出去;而bolt则负责转换这些数据流,在bolt中可以完成计算、过滤等操作,bolt自身也可以随机将数据发送给其他bolt。由spout发射出的tuple是不可变数组,对应着固定的键值对。
- Kafka
Kafka是由LinkedIn开发的一个分布式的消息系统,使用Scala编写,它以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark都支持与Kafka集成.
Kafka主要设计目标如下:
1)以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。
2)高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输。
3)支持Kafka Server间的消息分区,及分布式消费,同时保证每个Partition内的消息顺序传输。
4)同时支持离线数据处理和实时数据处理。
5)Scale out:支持在线水平扩展。
如上图所示,一个典型的Kafka集群中包含若干Producer(可以是web前端产生的Page View,或者是服务器日志,系统CPU、Memory等),若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息.
- ELKstack
ELKstack 是 Elasticsearch、Logstash、Kibana 三个开源软件的组合。在实时数据检索和分析场合,三者通常是配合共用,而且又都先后归于 Elastic.co 公司名下,故有此简称。
ELKstack 具有如下几个优点:
1)处理方式灵活。Elasticsearch 是实时全文索引,不需要像 storm 那样预先编程才能使用;
配置简易上手。Elasticsearch 全部采用 JSON 接口,Logstash 是 Ruby DSL 设计,都是目前业界最通用的配置语法设计;
2)检索性能高效。虽然每次查询都是实时计算,但是优秀的设计和实现基本可以达到百亿级数据查询的秒级响应;
3)集群线性扩展。不管是 Elasticsearch 集群还是 Logstash 集群都是可以线性扩展的;
前端操作炫丽。Kibana 界面上,只需要点击鼠标,就可以完成搜索、聚合功能,生成炫丽的仪表板。
- 容器与云计算篇
- 云计算:IaaS,PaaS和SaaS
- IaaS: Infrastructure-as-a-Service(基础设施即服务)
第一层叫做IaaS,有时候也叫做Hardware-as-a-Service,几年前如果你想在办公室或者公司的网站上运行一些企业应用,你需要去买服务器,或者别的高昂的硬件来控制本地应用,让你的业务运行起来。
但是现在有IaaS,你可以将硬件外包到别的地方去。IaaS公司会提供场外服务器,存储和网络硬件,你可以租用。节省了维护成本和办公场地,公司可以在任何时候利用这些硬件来运行其应用。
一些大的IaaS公司包括Amazon, Microsoft, VMWare, Rackspace和Red Hat.不过这些公司又都有自己的专长,比如Amazon和微软给你提供的不只是IaaS,他们还会将其计算能力出租给你来host你的网站。
- PaaS: Platform-as-a-Service(平台即服务)
第二层就是所谓的PaaS,某些时候也叫做中间件。你公司所有的开发都可以在这一层进行,节省了时间和资源。
PaaS公司在网上提供各种开发和分发应用的解决方案,比如虚拟服务器和操作系统。这节省了你在硬件上的费用,也让分散的工作室之间的合作变得更加容易。网页应用管理,应用设计,应用虚拟主机,存储,安全以及应用开发协作工具等。
一些大的PaaS提供者有Google App Engine,Microsoft Azure,Force.com,Heroku,Engine Yard。最近兴起的公司有AppFog, Mendix 和 Standing Cloud;
- SaaS: Software-as-a-Service(软件即服务)
第三层也就是所谓SaaS。这一层是和你的生活每天接触的一层,大多是通过网页浏览器来接入。任何一个远程服务器上的应用都可以通过网络来运行,就是SaaS了。
你消费的服务完全是从网页如Netflix, MOG, Google Apps, Box.net, Dropbox或者苹果的iCloud那里进入这些分类。尽管这些网页服务是用作商务和娱乐或者两者都有,但这也算是云技术的一部分。
一些用作商务的SaaS应用包括Citrix的GoToMeeting,Cisco的WebEx,Salesforce的CRM,ADP,Workday和SuccessFactors。
在当今云计算环境当中,IaaS是非常主流的,无论是Amazon EC2还是Linode或者Joyent等,都占有一席之地,但是随着Google的App Engine,Salesforce的Force.com还是微软的Windows Azure等PaaS平台的推出,使得PaaS也开始崭露头角。因为PaaS模式的高整合率所带来经济型使得如果PaaS能解决诸如通用性和支持的应用等方面的挑战,它将会替代IaaS成为开发者的“新宠”。
- Docker
Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。Docker自2013年推出以来非常火热,受到业界的广泛关注。Docker container和普通的虚拟机Image相比, 最大的区别是它并不包含操作系统内核.
- Docker特点:
- Docker核心技术:
1)隔离性: Linux Namespace(ns)
每个用户实例之间相互隔离, 互不影响。 一般的硬件虚拟化方法给出的方法是VM,而LXC给出的方法是container,更细一点讲就是kernel namespace。其中pid、net、ipc、mnt、uts、user等namespace将container的进程、网络、消息、文件系统、UTS("UNIX Time-sharing System")和用户空间隔离开。
2)可配额/可度量
Control Groups (cgroups)cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。groups可以限制blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns九大子系统的资源,以下是每个子系统的详细说明:
a、blkio 这个子系统设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb等等。
b、cpu 这个子系统使用调度程序为cgroup任务提供cpu的访问。
c、cpuacct 产生cgroup任务的cpu资源报告。
d、cpuset 如果是多核心的cpu,这个子系统会为cgroup任务分配单独的cpu和内存。devices 允许或拒绝cgroup任务对设备的访问。
e、freezer 暂停和恢复cgroup任务。
f、memory 设置每个cgroup的内存限制以及产生内存资源报告。
g、net_cls 标记每个网络包以供cgroup方便使用。
h、ns 名称空间子系统。
3)便携性: AUFS
AUFS (AnotherUnionFS) 是一种 Union FS, 简单来说就是支持将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)的文件系统, 更进一步的理解, AUFS支持为每一个成员目录(类似Git Branch)设定readonly、readwrite 和 whiteout-able 权限, 同时 AUFS 里有一个类似分层的概念, 对 readonly 权限的 branch 可以逻辑上进行修改(增量地, 不影响 readonly 部分的)。
通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个disk挂到同一个目录下, 另一个更常用的就是将一个 readonly 的 branch 和一个 writeable 的 branch 联合在一起,Live CD正是基于此方法可以允许在 OS image 不变的基础上允许用户在其上进行一些写操作。Docker 在 AUFS 上构建的 container image 也正是如此,接下来我们从启动 container 中的 linux 为例来介绍 docker 对AUFS特性的运用。
典型的启动Linux运行需要两个FS: bootfs + rootfs:
bootfs (boot file system) 主要包含 bootloader 和 kernel, bootloader主要是引导加载kernel, 当boot成功后 kernel 被加载到内存中后 bootfs就被umount了. rootfs (root file system) 包含的就是典型 Linux 系统中的 /dev, /proc,/bin, /etc 等标准目录和文件。
对于不同的linux发行版, bootfs基本是一致的, 但rootfs会有差别, 因此不同的发行版可以公用bootfs 如下图:
典型的Linux在启动后,首先将 rootfs 设置为 readonly, 进行一系列检查, 然后将其切换为 "readwrite" 供用户使用。在Docker中,初始化时也是将 rootfs 以readonly方式加载并检查,然而接下来利用 union mount 的方式将一个 readwrite 文件系统挂载在 readonly 的rootfs之上,并且允许再次将下层的 FS(file system) 设定为readonly 并且向上叠加, 这样一组readonly和一个writeable的结构构成一个container的运行时态, 每一个FS被称作一个FS层。如下图:
得益于AUFS的特性, 每一个对readonly层文件/目录的修改都只会存在于上层的writeable层中。这样由于不存在竞争, 多个container可以共享readonly的FS层。 所以Docker将readonly的FS层称作 "image" - 对于container而言整个rootfs都是read-write的,但事实上所有的修改都写入最上层的writeable层中, image不保存用户状态,只用于模板、新建和复制使用。
上层的image依赖下层的image,因此Docker中把下层的image称作父image,没有父image的image称作base image。因此想要从一个image启动一个container,Docker会先加载这个image和依赖的父images以及base image,用户的进程运行在writeable的layer中。所有parent image中的数据信息以及 ID、网络和lxc管理的资源限制等具体container的配置,构成一个Docker概念上的container。如下图:
4)安全性: AppArmor, SELinux, GRSEC
安全永远是相对的,这里有三个方面可以考虑Docker的安全特性:
由kernel namespaces和cgroups实现的Linux系统固有的安全标准;
Docker Deamon的安全接口;
Linux本身的安全加固解决方案,类如AppArmor, SELinux;
1)Mesos计算框架一个集群管理器,提供了有效的、跨分布式应用或框架的资源隔离和共享,可以运行Hadoop、MPI、Hypertable、Spark。使用ZooKeeper实现容错复制,使用Linux Containers来隔离任务,支持多种资源计划分配。
2)Mesos是如何让Twitter和Airbnb这样的公司,通过数据中心资源更高效的管理系统,扩展应用的呢?从一个相当简单但很优雅的两级调度架构开始说起。
上图修改自Apache Mesos网站上的图片,如图所示,Mesos实现了两级调度架构,它可以管理多种类型的应用程序。第一级调度是Master的守护进程,管理Mesos 集群中所有节点上运行的Slave守护进程。集群由物理服务器或虚拟服务器组成,用于运行应用程序的任务,比如Hadoop和MPI作业。第二级调度由被 称作Framework的“组件”组成。Framework包括调度器(Scheduler)和执行器(Executor)进程,其中每个节点上都会运行 执行器。Mesos能和不同类型的Framework通信,每种Framework由相应的应用集群管理。上图中只展示了Hadoop和MPI两种类型, 其它类型的应用程序也有相应的Framework。
Mesos Master协调全部的Slave,并确定每个节点的可用资源,
聚合计算跨节点的所有可用资源的报告,然后向注册到Master的Framework(作为Master的客户端)发出资源邀约。Framework可以 根据应用程序的需求,选择接受或拒绝来自master的资源邀约。一旦接受邀约,Master即协调Framework和Slave,调度参与节点上任 务,并在容器中执行,以使多种类型的任务,比如Hadoop和Cassandra,可以在同一个节点上同时运行。
- Marathon
Marathon是一个mesos框架,能够支持运行长服务,比如web应用等。是集群的分布式Init.d,能够原样运行任何Linux二进制发布版本,如Tomcat Play等等,可以集群的多进程管理。也是一种私有的Pass,实现服务的发现,为部署提供提供REST API服务,有授权和SSL、配置约束,通过HAProxy实现服务发现和负载平衡。
这样,我们可以如同一台Linux主机一样管理数千台服务器,它们的对应原理如下图,使用Marathon类似Linux主机内的init Systemd等外壳管理,而Mesos则不只包含一个Linux核,可以调度数千台服务器的Linux核,实际是一个数据中心的内核:
- Kubernetes
Kubernetes是Google开源的容器集群管理系统,其提供应用部署、维护、 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用,其主要功能如下:
1) 使用Docker对应用程序包装(package)、实例化(instantiate)、运行(run)。
2) 以集群的方式运行、管理跨机器的容器。
3) 解决Docker跨机器容器之间的通讯问题。
4) Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态。
当前Kubernetes支持GCE、vShpere、CoreOS、OpenShift、Azure等平台,除此之外,也可以直接运行在物理机上。
Kubernetes主要概念:
1) Pods
Pod是Kubernetes的基本操作单元,把相关的一个或多个容器构成一个Pod,通常Pod里的容器运行相同的应用。Pod包含的容器运行在同一个Minion(Host)上,看作一个统一管理单元,共享相同的volumes和network namespace/IP和Port空间。
2) Services
Services也是Kubernetes的基本操作单元,是真实应用服务的抽象,每一个服务后面都有很多对应的容器来支持,通过Proxy的port和服务selector决定服务请求传递给后端提供服务的容器,对外表现为一个单一访问接口,外部不需要了解后端如何运行,这给扩展或维护后端带来很大的好处。
3) Replication Controllers
Replication Controller确保任何时候Kubernetes集群中有指定数量的pod副本(replicas)在运行, 如果少于指定数量的pod副本(replicas),Replication Controller会启动新的Container,反之会杀死多余的以保证数量不变。Replication Controller使用预先定义的pod模板创建pods,一旦创建成功,pod 模板和创建的pods没有任何关联,可以修改pod 模板而不会对已创建pods有任何影响,也可以直接更新通过Replication Controller创建的pods。对于利用pod 模板创建的pods,Replication Controller根据label selector来关联,通过修改pods的label可以删除对应的pods。
4) Labels
Labels是用于区分Pod、Service、Replication Controller的key/value键值对,Pod、Service、 Replication Controller可以有多个label,但是每个label的key只能对应一个value。Labels是Service和Replication Controller运行的基础,为了将访问Service的请求转发给后端提供服务的多个容器,正是通过标识容器的labels来选择正确的容器。同样,Replication Controller也使用labels来管理通过pod 模板创建的一组容器,这样Replication Controller可以更加容易,方便地管理多个容器,无论有多少容器。
Kubernetes整体框架图如下,主要包括kubecfg、Master API Server、Kubelet、Minion(Host)以及Proxy;
- 总结
通过这次大会的交流学习,不能说掌握了多少专业的细节知识,但绝对是眼界开阔了些;了解了业界软件发展的技术动态,知道了行业公司在软件开发流程中遇到的问题及解决方案。在面对日新月异的技术发展,我认为有几个原则需要坚守下:
- 及时了解新的技术动态和行业的发展方向;
- 重视开源技术的发展,几乎影响力很大的技术都来源于开源社区;
- 架构设计,应已简单实用为目标,环境需求为根本;不要盲从高大上的系统;
- 敢于引进新的技术,没有最稳定的系统只有不断改进的系统;