This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
<audio id="audio" title="09 | 什么是PaaS怎样深入理解和评估PaaS" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/63/3a/63ad67027a5095918acf6c99b665803a.mp3"></audio>
你好,我是何恺铎。
欢迎你来到我们《深入浅出云计算》课程的第9讲这也是我们PaaS篇的第1讲。让我们继续精彩的云计算之旅。
PaaS对你来说也许不是一个陌生的词汇你可能早已从业界大咖或身边同事的高谈阔论中屡次听到这个字眼。不过很多人对于PaaS服务的评价可是既有“真香快来”的赞赏也不乏“大坑勿入”的批评面对如此两极分化的评价你估计也有点拿不定主意。这些如雷贯耳的PaaS服务们究竟靠不靠谱、好不好用呢
作为极客时间的一名“极客”咱们人云亦云可不行必须要建立起对PaaS的系统认知。从今天开始我们就来好好地研究一下PaaS。
让我们先从它的定义说起。
## 什么是PaaS
在IaaS篇中我们主要是侧重于基础设施类的云服务尤其是虚拟机、云磁盘、云网络等服务。它们的特点是和传统IT基础设施往往有一个对应关系所以被称为基础设施即服务Infrastructure-as-a-Service
今天我们的主角**PaaS** Platform-as-a-Service则是指云计算提供的平台类服务在这些平台的基础上用户可以直接开发、运行、管理应用程序而无需构建和维护底层的基础设施。
用更通俗的话来说,**PaaS是在IaaS的基础上又做了许多工作构建了很多关键抽象和可复用的单元让我们用户能够在更上层进行应用的构建把更多精力放在业务逻辑上。**
拿房子装修来打个比方的话IaaS就好像空空如也的毛坯房我们还需要操心墙面、地板等基础性工作而PaaS就好比精装修的房子我们只要搬入自己喜欢的家具业务逻辑再适当装饰就可以“拎包入住”开始美好生活了。
小提示PaaS本身也是基于底层IaaS构建出来的使用了云上的各种基础设施。只是这个步骤云服务提供商代替我们用户完成了还进行了一定程度的封装。
当然随着PaaS服务形态种类的增多、边界的不断扩展除了那些包含语言运行环境、可编程和可扩展的经典PaaS服务之外还有更多的在云上用来辅助应用构建或帮助运维的服务也归入了广义上PaaS的范畴。这也是有道理的因为它们同样是完整的现代应用程序生态的一部分。
## PaaS服务的核心优势是什么
如果你去回顾云计算的历史可能会惊奇地发现PaaS并不是在IaaS已经非常丰富和完善之后才出现的它们甚至可以说是“同龄人”。因为在云计算发展的初期不同公司选取了不同的发展路线有的侧重IaaS有的则先押宝了PaaS路线。
拓展不论是IaaS还是PaaS想要做好都不容易需要云厂商很大的投入。如果你对于相关的早期历史有兴趣可以参考我在InfoQ上发表的文章[《激荡十年:云计算的过去、现在与未来》](https://mp.weixin.qq.com/s/AZV2ejFGjDnJ_488XoUWYA)。
从某种角度讲PaaS其实更符合云的初衷它代表了一种完全托管的理想主义也更能代表人们对于研发生产力的极致追求。
**所以PaaS服务的优势就在于生产力在于效率尤其是在搭建和运维层面。**比如我们课程后面会讲到大数据类的PaaS服务你可以很方便地一键启动规模庞大的大数据集群即刻开始运行分布式计算任务。想一想如果是由你自己基于虚拟机来进行搭建的话肯定得花上不少功夫。
进一步地来说云上的各种PaaS服务是可以互相配合叠加的。运用得当的话它们联合起来爆发出来的能力会非常强效率优势会更加凸显出来。
这里我给你举一个例子来说明一下PaaS服务的优势。
**日志服务**是我们应用程序后端不可或缺的一个组件通常我们会组合使用ELKElasticsearch+Logstash+Kibana技术栈来自行搭建一个日志存储和分析系统。
而在云上你可以轻松地找到PaaS服务来为你代劳。比如阿里云日志服务就提供了一个端到端的日志收集、查询、分析和可视化的解决方案。在这个过程中你不需要搭建和维护任何基础设施只要按照产品提示进行设置就可以了。
利用阿里云的日志服务我大概花了1分钟的时间就建立了一个日志服务实例并让它收集某个虚拟机/ data目录下的日志文件。随后我在目录中放置了一本小说《双城记》很快这个文本文件就被自动传送到了日志服务并索引起来。然后我就可以利用PaaS的功能来进行各种查询分析了。
下图为我搜索单词“happiness”的效果示例
<img src="https://static001.geekbang.org/resource/image/ca/81/cadadfb4a05f9ed30ff94420d154f381.jpg" alt="">
## 怎样入手学习研究PaaS
由于软件构造的复杂性用户对于可复用组件的需求是非常多的。所以经过多年的发展下来云上的PaaS已经是琳琅满目、种类繁多。我们后面的课程也会陆续地讲解各种不同形式、服务不同目的的PaaS服务。
但在那之前我想告诉你观察和认知PaaS服务的方法。这里有几个重要的维度值得你探寻和了解让你能在清楚了它本身的业务用途之外还可以洞察这个服务在产品设计和内部实现方面的一些信息。
**第一个维度,就是服务是否带有内生的运行环境。**
我个人把它称为“承载性”即服务有没有运行时或执行环境来承载我们具体业务逻辑的代码或配置。如果有那么你需要去熟悉它的运行环境了解它支持的语法探寻各种参数设置。比如说Web服务可能带有Java、.NET等的运行时数据库服务可能会包含SQL的执行引擎。
如果没有内含的运行环境那就说明这个PaaS属于“开箱即用”的工具类型也就是直接依靠自身内置功能来向你提供支持或帮助。这时它功能的完善程度以及和你需求的匹配程度就比较关键了。
**第二个维度是PaaS服务存在的位置和范围以及给予你的控制粒度。**
这个怎么理解呢其实就是当你新建一个PaaS服务的实例你一般会需要告诉系统部署的目标位置在哪里。请你注意这个目标位置的选项是值得玩味的。比如你要仔细看看这个服务是只能粗放地允许你指定区域还是可以细化到可用区以及是否能够设置为部署在具体某个私有网络之内等等。
这个维度的信息一方面潜在地体现了PaaS服务的规模和可用性。比如云存储类服务一般只能让你选择区域因为它本身冗余性方面的多可用区架构要求决定了它无法支持指定更精细的位置。
另一方面这个维度也反映了你对这个服务的掌控程度你会知道它是否能够和你现有的架构进行深度集成。比如说你很可能要求数据库PaaS服务必须位于你指定的VPC内这样查询流量就能走内网通信避免对公网暴露数据库。
**第三个维度,在于服务是否是“有状态”的,也就是指服务是否具有较强的数据属性。**
有些PaaS服务本身是无状态的比如无服务器函数这意味着它们比较容易扩展和提升规模有些PaaS服务则会保存状态或者说建立的初衷就是为了维护各种复杂的状态和数据。这对应着PaaS在计算存储能力输出上的不同角色和分工。
**第四个维度体现为支撑PaaS的虚拟机是否对外暴露也就是会不会显示在ECS、EC2等虚拟机服务的门户列表中。**
这是一个很有趣的视角。因为作为PaaS实现者云厂商既可以选择开放也可以不开放。有时针对同一类的服务不同的云也可能采用不同的做法这体现了云厂商在规划产品上的不同思路也和它们各自的实现原理有关。
通常来说暴露虚拟机的PaaS服务拥有更高的开放程度和IaaS的结合也更加紧密甚至能够和其他IaaS服务配合联动。在成本方面这种形式还可以和预付费的虚拟机兼容让我们享受折扣。
而不暴露虚拟机的PaaS服务呢往往意味着更好的独立性和封装性说明它不希望你绕开机制来访问虚拟机比如大多数的数据库服务。还有一种常见的可能是这个服务需要专用硬件的配合并非纯粹依赖虚拟机。
好了有了上面的这些视角相信你即便是对于一个新的PaaS服务在快速研究之后也能迅速地把握好要点并进行归类同时形成清晰的高层次认识。对于它是否适合在你的架构中担任角色你也会有一个大致的判断。
## 衡量评估PaaS的局限
我们都知道软件工程的领域没有银弹。强大的PaaS也不例外也有自己的局限。
**PaaS的核心理念在于封装封装既带来了效率的优势也同时带来了灵活性上的牺牲。**我们需要在内置的设定和选项中开展工作不能天马行空、随心所欲。PaaS的应变能力也会差一些比如当它出现一些Bug或者运营事故时你无法自己动手去解决它而是需要等待厂商进行修复。
这是PaaS诞生以来就伴随着质疑的原因你的身边可能就有PaaS的反对者。有些以前只做PaaS的公有云公司也不得不向市场妥协陆续开始了IaaS产品的研发。这和早期云市场的接受程度有关也和当时PaaS自身的成熟度有关。
当然这里我讲的局限性不是为了奉劝你远离PaaS而是让你能更加客观地看待PaaS这个产品形态更好地评估某项PaaS服务是否适用于你的场景。因为PaaS在带来巨大效率提升的同时也的确要牺牲一点“自由”。
这里我要给你介绍一些检查PaaS限制的方法也是考察评估PaaS服务成熟度的重要思路你需要好好参考和把握。
- **功能屏蔽**和自建服务相比你需要研究PaaS的封装是否带来了某项功能、部分选项还有扩展机制的屏蔽或者缺失以及这些功能对你而言是否重要。
- **版本选择**你需要检查PaaS所提供的软件或运行环境的版本是否丰富最早和最新的版本各是什么还有版本粒度是否足够细致等等。我就曾经遇到过因为所需数据库版本在PaaS上不存在只能选择虚拟机进行部署的情况。
- **性能极限**确认PaaS服务所能够提供的性能极值包括算力和存储的上限。你要和自己的需求量预测结合起来避免“上车”后骑虎难下。
- **更新频率**查看PaaS服务的更新日志了解云厂商和相应团队在这个PaaS服务上是否还在继续做投入是否在跟进一些最新的技术趋势。
- **成本陷阱**实际地通过POC实验对PaaS服务进行试运行注意要达到一定的量级然后仔细查看它对应的账单看看相关支出是否合理你能否长期承受。
所以对于PaaS来说其实设置界面选项越多往往越好这也不失为一个甄别产品成熟度的简单办法。你不应该担心产品学习曲线陡峭的问题这些不起眼的选项很可能在某个时刻被派上用场发挥关键的作用。
我还是要再次强调你应当理性地看待PaaS。它肯定不是无所不能但也绝非一无是处。更客观地学习了解它有助于建立你对PaaS的理解和信任在合适场景下最大化地发挥它的优势和价值。
我个人对于PaaS还是非常看好的它近年来日新月异的发展已经极大地提升了竞争力。随着大量用户的不断实践和反馈这些产品也越来越开放突破了过去的很多限制。有时即便PaaS相对自建会稍微贵一些我也会优先选择PaaS因为它带来的效率提升和时间人力的节省远远超出了贵出的那点价格。
最后我想再补充一点当云上官方的PaaS不足以满足你的需求时还有第三方PaaS是值得考虑的选择你通常能够在云厂商的各种云应用市场中找到它们。比如说大数据领域中炙手可热的Databricks公司就分别在AWS和Azure云都上架了自家的PaaS服务比起内置大数据的云服务来说也毫不逊色。
## 课堂总结与思考
作为PaaS篇的第一讲我就先和你讨论到这里了。希望通过今天对PaaS的讲解能够给你建立起一个对PaaS宏观层面的正确认识。同时我今天介绍的几个观察评估要点的确是你研究PaaS时值得参考的良好视角。后面在跟随课程讲到具体的各个PaaS服务的时候也请你记得时不时地回看这一讲的内容相互印证。
我自己是一个PaaS的乐观主义者。如果把你要构建的应用比作高楼大厦那么PaaS作为大厦的基石和支柱它是当之无愧、值得信赖的。在充分客观了解PaaS局限的前提下你不妨积极大胆地拥抱PaaS吧。
**好了,今天我留给你的思考题是:**你目前接触使用最多的PaaS服务是哪个它给你带来了怎样的效率提升同时它有没有什么局限让你伤脑筋呢
欢迎你在下方留言。如果你觉得这篇文章有帮助,欢迎你把它分享给你的朋友。我是何恺铎,感谢阅读,我们下期再见。

View File

@@ -0,0 +1,180 @@
<audio id="audio" title="10 | 对象存储:看似简单的存储服务都有哪些玄机?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/bb/b4/bba42f3c9ce2cd648c8b781ff3b417b4.mp3"></audio>
你好我是何恺铎。今天起我们展开来讲具体的PaaS服务。
我第一个要深入介绍的服务,当仁不让就是**对象存储**Object Storage了。因为它可以说是应用最广泛、最常见的基础性PaaS服务了几乎每个云上的项目都会用到它。
对象存储,顾名思义,就是在云端,你可以存放任意对象的存储服务。你要注意,**这里的“对象”指的是任意的二进制对象,保存到云上通常是以二进制文件的形式,你不要和“面向对象编程”中的对象混淆起来。**
对象存储的历史说起来和云计算一样悠久。AWS著名的对象存储服务S3Simple Storage Service早在2006年就发布了甚至比它的虚拟机服务EC2还要早上几个月。
S3对象存储服务从一开始发布就以其简明易用、高可用低成本的特点很快受到了市场的广泛欢迎。各个云计算厂商也纷纷跟进推出了自己的对象存储产品。到现在对象存储已经是云计算领域的“标配”了。
说到这里你可能会问,对象存储听上去的确很简单,无非就像一个文件服务器而已,需要用单独的篇幅来展开介绍吗?
答案当然是**肯定的**。要知道,对象存储不但注重打造存储的核心能力,还建立了一整套成熟的管理控制机制,更能够方便地与各种应用程序集成。所以,它值得我们来好好看一看。
注:对象存储是如此的成功,以至于有时候人们会用“云存储”来称呼它。但理论上来说,云存储是一个更加宽泛的概念,可以包含多种云上存储产品。我们这里还是更严谨地称之为对象存储。
## 初识对象存储
那么,对象存储,究竟为我们提供了什么功能呢?
通俗地解释起来,你可以这样理解,对象存储是你在云上可以创建的一种“网盘”。这个网盘可以存储任意的二进制文件,包括结构化和非结构化数据。你可以随时上传下载,也可以修改和删除。当然,云上对象存储会保证你数据的可靠性、可用性和扩展性,你不需要操心这些细节。
那么,**同样是存储服务对象存储和前面我们IaaS部分讲过的[云硬盘](https://time.geekbang.org/column/article/210423)有什么区别呢?**
这是好问题。这两者之间,虽然都是存储服务,也都有多副本的冗余机制,但还是有相当大的区别。
**第一个主要区别,在于访问的接口与形式。**
云硬盘其实是挂载到虚拟机的虚拟硬盘,它是通过实现操作系统级别的底层接口,作为虚拟机的**块存储设备**而存在。我们也必须连接到相关的虚拟机,才能访问它里面的数据。
而对象存储,本质是一个**网络化的服务**调用方主要通过高层的API和SDK来和它进行交互。不管是面向外部公开互联网服务还是和内部应用程序对接对象存储都是通过提供像HTTP这样的网络接口来实现的。所以它的独立性很强不需要依赖其他组件就可以运作。
这也正是我们把对象存储放在PaaS篇而不是IaaS篇中讲解的原因。虽然它的功能很“基础”但它的产品形态是非常典型的PaaS因为你不需要操心下面支撑它的具体机器和可用性等等问题只需要依赖它在它之上构建你的应用就行了。
注意尽管有S3FS、OSSFS等工具也可以模拟磁盘并挂载到虚拟机但它们也是基于对象存储的API进行了封装并不改变对象存储是网络化服务的本质。
**第二个主要区别也是对象存储的一大特征就是对象存储内本身不存在一个真正的文件系统而是更接近一个键值Key-Value形式的存储服务。**
这里的键就是对象的路径(路径中包含斜杠符号“/”),这里的值就是存储对象的二进制文件。
键值系统和云硬盘上经典文件系统的**核心差异**,就在于文件系统保存了更多的元数据,尤其是实现了目录结构和目录操作。而键值系统中,所谓的目录其实是多个对象共享的路径前缀,可以说是用前缀模拟出了目录。
这个键值系统的设计理念,给对象存储带来的好处就是简化了逻辑和设计,可以让云厂商把更多精力放在对象存储的分布式架构和服务高可用上面。
当然相应地,这样的设计也使得对象存储中的“目录”操作代价变高了,比如说目录的删除和重命名,我们就需要对目录下所有的对象文件进行修改或删除来模拟。所以,很多对象存储系统都默认不提供目录级别的操作功能,或是性能相对较差,这一点我们需要注意。
**第三个主要区别,在于对象存储的巨大容量。**
作为云计算最具代表性的服务之一,它的**可扩展性**Scalability是毋庸置疑的对象存储能够轻松地容纳上PB的超大容量数据这是任何的云硬盘所不能企及的。所以**对象存储是名副其实的大数据存储。**
但从另一个角度说对象存储和HDFS这样的大数据文件系统比起来又有自己独到的优势对象存储本身也是非常擅长和适合处理小文件的即便是海量的小文件对象存储也不会像HDFS那样处理起来捉襟见肘可以说是“大小通吃”。
好的,现在我们不但把对象存储和云硬盘的区别搞清楚了,同时也理解了对象存储的最主要特征。
百闻不如一见,我们接下来进行**实操**。这次的实验我们使用国际版AWS S3当然你也可以使用阿里云OSS和Azure Blob Storage等类似服务进行体验。
首先我们在S3门户创建一个基本的存储桶geektime-hellocloud。这个存储桶你可以认为是一个对象存储的基本容器这里的名称一般要求全球唯一在区域方面我们选择美国西部。
<img src="https://static001.geekbang.org/resource/image/16/a4/163442b834f1ed7b35f2d1cb9d8d4aa4.jpg" alt="">
随后我们点击进入这个存储桶实例上传一个用于实验的文本文件我们还是使用小说《双城记》的文本ATaleOfTwoCities.txt。成功上传后能够看到文件已经存在于桶内。
<img src="https://static001.geekbang.org/resource/image/64/19/64568698e0ee062e44f1c7bc6f650a19.jpg" alt="">
<img src="https://static001.geekbang.org/resource/image/30/2f/3011e6e4ac098ded84f0e6edfa436a2f.jpg" alt="">
点开这个文件,我们可以查看这个对象的一些基本属性,也能够进行一些基本操作。
<img src="https://static001.geekbang.org/resource/image/fe/21/fe26f09b91b412a989f97aa9f0ee5921.jpg" alt="">
在上图中点击“复制路径”按钮你会得到一个URL为
>
**s3://geektime-hellocloud/ATaleOfTwoCities.txt**
这是使用S3标准协议下的对象路径它也是对象的唯一标识。这个路径可以在所有支持S3协议的场景下使用比如AWS的命令行工具。
下面展示了使用AWS CLI的s3命令把我们这个文件下载到虚拟机当前目录的方法事先我们已使用aws configure登录
```
[ec2-user@ip-xx-xx-xx-xx s3test]$ aws s3 cp s3://geektime-hellocloud/ATaleOfTwoCities.txt .
download: s3://geektime-hellocloud/ATaleOfTwoCities.txt to ./ATaleOfTwoCities.txt
[ec2-user@ip-xx-xx-xx-xx s3test]$ ls
ATaleOfTwoCities.txt
```
**注意**前面对象属性截图的底部红框中的“对象URL”还提供了一个HTTP协议的对象路径你一定不要把它和S3协议的路径混淆起来因为这两者是用于不同的环境的。HTTP协议的URL可以让通用的Web客户端直接访问这个对象。
不过现在如果我们直接请求这个URL的话我们会吃一个闭门羹
```
[ec2-user@ip-xx-xx-xx-xx s3test]$ curl -I https://geektime-hellocloud.s3-us-west-1.amazonaws.com/ATaleOfTwoCities.txt
HTTP/1.1 403 Forbidden
...
```
这是因为在默认情况下这个URL并不对公开互联网开放你需要手动地在权限管理Tab中打开这个限制
<img src="https://static001.geekbang.org/resource/image/35/8e/352549bc38cd53644e2e87e750e6dd8e.jpg" alt="">
打开公有访问权限后再次实验,我们就能够成功地访问到文件的内容了:
```
[ec2-user@ip-xx-xx-xx-xx s3test]$ curl -s https://geektime-hellocloud.s3-us-west-1.amazonaws.com/ATaleOfTwoCities.txt | head
The Project Gutenberg EBook of A Tale of Two Cities, by Charles Dickens
This eBook is for the use of anyone anywhere at no cost and with
almost no restrictions whatsoever. You may copy it, give it away or
re-use it under the terms of the Project Gutenberg License included
...
```
注意:打开对象存储的公开访问需要非常小心。历史上出现过非常多次因为误设置了公开权限而导致重要数据泄露的事故。一般来讲,更推荐使用更严格的基于身份认证的访问模式。
你看对象存储是不是特别简明易用而且得益于自带的冗余机制它一般都有高达99.999999999%11个9的数据可靠性上传到其中的数据几乎可以说是万无一失了。再结合它低成本的特点来看对象存储也非常适合作为数据备份的场所。
## 对象存储的高级特性
学习了对象存储的基本知识和操作之后,接下来我们探讨一些它的高级特性。即便你是对象存储的熟手,这里面也很可能有一些你之前并不了解的门道。
**第一个重要特性,是存储分层。**
在生产环境下的对象存储,我们往往会存放大量的文件和数据,这些文件的访问频率其实是会有很大差异的。比如说,对于一些比较热门的下载文件,它可能经常需要被访问调用;而如果是一些明细的日志文件,写入后再次读取的机率通常不高,只有当排查问题时,我们才可能去访问翻看它。
所以为了应对不同的访问模式和频率,对象存储贴心地提供了分层的策略,你可以按照访问热度,设置**从热到冷**不同的存储级别(或者叫存储类型)。其中,存储级别为**热**的对象,存储空间占用的**成本稍高**,但访问读取不需要收取额外的费用;而存储级别越**冷**,则存储空间的单位**成本越低**,但访问读取需要收取一定的费用。到了极少访问的存档级别,数据的“解冻”可能还需要花费一些时间。
不同云的存储级别叫法有一些区别,我这里用一个表格给你做了大致的梳理:
<img src="https://static001.geekbang.org/resource/image/8e/0b/8e9714638c46dac5e8b241b0958cc30b.jpg" alt="">
所以,这些存储级别其实是一种在访问效率和存储成本之间的平衡。对象存储服务把这样的一个选择权开放出来,是一个非常有用的特性,能够让你根据具体的文件情况,因地制宜,选择不同的策略。而且这些策略既可以是存储桶级别的,也可以细到单个文件,非常灵活。
重要提示:同一个文件的存储类型是可以按需转换的,既可以从热到冷,也可以从冷到热。但你需要注意,这个切换动作本身可能会收取额外的费用,所以不应该经常地切换,这样会得不偿失。
可以说,**存储分层的存在,让原本价格低廉的云上存储更加具有成本竞争力。**给你举个例子现在归档层的存储费用在典型情况下大约是每GB每月1分钱左右是不是低得惊人所以很多用户上云的一个应用场景就是把原本占用大量传统磁盘的备份文件利用对象存储的归档能力长期保存。
**第二个值得称道的特性,是生命周期管理。**
随着时间的推移、业务的增长,你在对象存储中的内容肯定会越来越多。当总的体量和对象的个数到达一定级别的时候,你会发现对历史内容进行清理就成为了一件非常麻烦的事情。
这时候生命周期管理功能就可以很好地帮助我们。因为它允许你设置一定的过期规则当对象满足规则时通常每天判断一次可以自动地执行一些清理操作。比如你可以对一个存储桶或目录进行设置要求最后修改时间超过60天的文件自动切换到低频访问层超过180天的文件则进行归档或删除。
我曾经就在某个生产环境中,启用了这个自动清理特性,立竿见影地节省了大量成本,如下图所示。
<img src="https://static001.geekbang.org/resource/image/29/18/296fe2fb37b6a8b92067059d25345e18.jpg" alt="">
**第三个特性则是对象的版本管理Versioning。**
这个很好理解。同一个对象可能会被修改更新,而启用这个特性后,对象存储系统就能够自动地帮助你记录这个对象之前的多个版本。这样,当有需要时,你可以按需进行回滚和恢复,能避免不必要的损失。
此外,对象存储服务还有跨区域同步、访问日志分析等其他高级特性。前者可以帮助你自动对数据进行跨区域同步,常用于重要数据备份或热点数据分发,后者则对已经存放了海量数据的对象存储进行管理分析大有帮助。有兴趣的话,你都可以自己尝试一下。
## 对象存储的应用场景
我们的应用离不开数据,所以几乎到处都是对象存储可以发挥的场景。**一切需要保存数据的地方,不论是原始数据的保留备份、中间结果的临时落地,还是处理结果数据的永久保存,你都可以考虑对象存储是否适用。**
是的,在很多系统中,对象存储就是这样贯穿在整个系统数据流程的生命周期中,串联起了数据处理的各个环节。对象存储有时甚至还可以用来做简单的键值数据库,由于它的分布式设计,对它来说,承担大量的并发请求,也是小菜一碟。
对象存储还可以支撑大数据应用。现在各云厂商的对象存储服务也普遍地作为分布式存储系统与各家的大数据PaaS产品进行了深度的集成也是云上各类数据湖解决方案的关键组成部分。我们后面讲到[大数据PaaS服务](https://time.geekbang.org/column/article/218985)时还会详细讨论。
最后通过前面的实验我们能看到对象存储可以直接面向公开互联网作为文件服务器对外提供服务。通过妥善设置对象的HTTP响应头它甚至还能支撑起静态网站免去我们创建虚拟机的麻烦。如果下载量比较大且对带宽延时有更高要求的话它又能无缝地与云上的CDN服务进行集成作为CDN的回源站点。
## 课堂总结与思考
因为对象存储的高可用、低成本的特性让它成为了云上最重要、最受欢迎的支柱性PaaS服务之一也极大地助推了云计算本身的发展。它上手起来非常简单而深入运用起来又很强大可以说是产品设计上的最高境界了。
对象存储在实践中实在有太多妙用,等待着你去感受和发现。我建议你多多实际操作,探索一遍它的各个功能选项,这会比你单纯地阅读产品文档有更深入的体会。
**今天给你的思考题是这样的,欢迎你在留言区和我互动:**
- 将对象设置为完全公开是非常危险的,但如果我们要临时地分享一个对象,给特定的外部用户,应该怎样做呢?
- 假设你在本地数据中心,有大量的数据需要上传到云对象存储中,但互联网的带宽有限,上传需要很长的时间。对于这种情况有什么好办法吗?
好了,这一讲我们就到这里。如果你觉得有收获,也欢迎你把这篇文章分享给你的朋友。感谢阅读,我们下期再见。

View File

@@ -0,0 +1,167 @@
<audio id="audio" title="11 | 应用托管服务Web应用怎样在云上安家" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/75/68/753e706611d8bab26c3b5b2755055468.mp3"></audio>
你好,我是何恺铎。今天我们来谈谈云上的应用托管服务。
从互联网诞生开始,网站就一直是人接触内容的主要窗口,是互联网应用的主要形态。所以许多的编程语言和技术栈在争夺开发者的时候,都是以支持网站应用的开发作为主要的发力点。
这个浪潮催生了各类动态网站编程技术和各种Web后端框架的兴起。而随着AJAX应用和移动互联网的到来Web已经不只是网站了它还包括各种各样的API。我们可以把它们统称为Web应用。
Web应用显然是一个极为普遍的需求也是一个巨大的市场。所以作为承载一切的云计算当然需要为Web应用的运行提供最好的场所、能力和辅助。
不过你当然也可以使用虚拟机和其他IaaS组件来搭建你的网站。但用IaaS你需要操心的事情比较多包括虚拟机的创建、运行环境的搭建和依赖安装、高可用性和水平扩展的架构等等。而且一旦应用的规模大了每次应用的更新升级也会是件麻烦事另外你还要操心Web漏洞的弥补修复。
**那么,能不能有一个平台服务,来帮助我们解决所有这些基础架构问题,让我们只需要专注于应用构建本身就好了呢?**当然是有的这就是云上应用托管PaaS服务的由来。
## 什么是应用托管服务?
和每一项云服务一样,应用托管类服务也是从简单到复杂、从功能单一到丰富强大这样一路走来的。
在云计算发展的早期,就已经出现了“**建站类服务**”这正是应用托管服务的雏形。当时的建站类服务会自动为你分配好服务器安装好相应语言的Web环境以供你使用。在部署层面服务通常会开放FTP端口以便你上传服务器端的代码、脚本和资源。这是应用服务的一种轻量形式。
注意目前仍然有云厂商提供了这种轻量Web服务的产品形态比如阿里云的轻量应用服务器、百度云虚拟主机服务等。这些服务仍然可用而且由于使用简单且成本低廉在合适的场景下比如中小企业建站也是不错的选择。
而更现代的应用托管服务,已经今非昔比,不但在细节选项、自动化程度上进步了许多,还包含了大量的增值服务。如果你的运用得当,它绝对是一个利器,能为你节省许多的时间精力。
这类现代应用托管服务现在是各个云上的标配AWS上对应的云服务为Elastic Beanstalk阿里云对应的服务为Web应用托管服务Web+Azure上称之为Azure应用服务Azure App Service
接下来我就以国际版的Azure应用服务为例把我们在[第7讲](https://time.geekbang.org/column/article/212714)中使用过的计算**斐波那契数列**的Web应用移植到Azure云的PaaS服务上来。
首先,我们来创建一个应用服务的实例:
<img src="https://static001.geekbang.org/resource/image/9f/e0/9f212fe9b3b390bb6b5917ede9d293e0.jpg" alt="">
在上图中,我填写了一些重要信息,比如把这个实例称为 **fibonodejs**,系统会自动给它一个免费的域名 **fibonodejs.azurewebsites.net**。另外我还选取了Node技术栈以及Linux操作系统。在运行配置方面我选取了**标准S1**对应一个vCPU和1.75GB内存的计算资源。
**这里你需要注意**除了Node技术栈之外一般云厂商都会提供Java、PHP等多个常用语言和框架的支持。你可以事先确认一下你偏爱的语言是否在云厂商的支持列表中。下面我还列出了Azure应用服务支持的部分环境可以看到同一个语言或框架还支持很多不同的版本所以我们的选择是很丰富的。
<img src="https://static001.geekbang.org/resource/image/b5/ce/b5a391e53f9d6a3c3c9926acef386fce.jpg" alt="">
实例创建完毕后,就相当于我们已经建好了房子,接下来的关键就是要**邀请应用入住**。
我们在第7讲中使用过的app.js中的源码在这里基本不需要修改就可以直接使用了唯一需要适配一下的是最后监听的**端口号**我们需要从固定值80修改为**动态值process.env.PORT**。这个动态值会在应用运行时从PaaS服务的环境变量中得到。
```
app.listen(process.env.PORT);
```
随后我们只需要把应用的代码打包上传就可以了。我们这个Node应用比较简单只是包含一个app.js和package.json配置文件。**package.json配置文件**的内容也很简洁,只有少数包依赖,以及一个初始化的启动命令:
```
{
&quot;name&quot;: &quot;fibo-app&quot;,
&quot;version&quot;: &quot;0.0.1&quot;,
&quot;private&quot;: true,
&quot;scripts&quot;: {
&quot;start&quot;: &quot;node ./app.js&quot;
},
&quot;dependencies&quot;: {
&quot;express&quot;: &quot;4.0.0&quot;,
&quot;ip&quot;:&quot;1.1.5&quot;
}
}
```
我们再新建一个 **.deployment文件**其中设置SCM_DO_BUILD_DURING_DEPLOYMENT参数为 **true**。**这个设置会告诉Azure PaaS端在部署时帮我们自动执行npm install来安装依赖项。**
```
[config]
SCM_DO_BUILD_DURING_DEPLOYMENT=true
```
然后,我们把上面提到的这三个文本文件一起**打包为zip**
```
[client@clientVM fiboapp]$ zip fiboapp.zip app.js package.json .deployment
updating: app.js (deflated 48%)
updating: package.json (deflated 30%)
updating: .deployment (stored 0%)
```
接下来十分关键的一步是我们要用Azure CLI中的 **webapp相关命令**完成zip文件的上传。
```
[client@clientVM fiboapp]$ az webapp deployment source config-zip --resource-group geektime-hellocloud --name fibonodejs --src ./fiboapp.zip
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
```
我们需要做的就只有这些。当Azure应用服务收到zip包后就会在一个隔离环境中自动解压、安装相关依赖项并开始运行我们的应用了。
尝试一下网站服务,已经在正常地工作了:
```
[client@clientVM ~]$ curl https://fibonodejs.azurewebsites.net/
I am healthy
[client@clientVM ~]$ curl https://fibonodejs.azurewebsites.net/fibo/35
Fibo(35) = 14930352
Computed by 49fe1eef783e with private ip 172.16.1.4
```
通过这个例子,你能够看出,**应用服务的本质就是为你的应用提供一个隔离的独立运行环境。**作为用户来讲,你可以只专注于业务逻辑,不需要来手动创建这个环境,更不需要运维这个环境。
小提示应用托管服务背后采用的隔离技术对用户一般是不可见的它可能是虚拟机可能是Docker或者是自研的其他容器类技术。通过查看后台日志你可以发现Azure App Service在Linux上的后台其实是使用了Docker来封装运行我们的node.js程序。
另外,为了便于说明操作步骤,上面的实操中,我使用了**命令行**的方式来进行应用的打包和部署。如果你觉得这个过程有点儿麻烦也完全可以借助一些IDE工具来完成它。比如说你可以使用Visual Studio Code配合App Service插件来进行开发和部署。
而且,上面的打包上传等步骤,我们在集成环境中,只需要按下“**Deploy to Web App**”,一键就可以完成了,如下图所示:
<img src="https://static001.geekbang.org/resource/image/a6/8f/a636d762e2965d4dbdd37c6f3238668f.jpg" alt="">
所以云厂商为了提高PaaS服务的易用性往往会有比较成熟的开发配套工具链可以选用这也是应用托管服务的一大优势。
## 应用托管的增值服务
上面我通过例子,给你演示了一下应用服务的基本功能,但它的能力远不止此。成熟的应用服务还能够提供许多**增值服务**来进一步地满足我们在实际开发运维Web应用时产生的各个层面的需求。
**第一项增值服务就是监控**尤其是针对Web应用的特点而进行的HTTP层面的应用监控。所以你不仅能看到计算资源的占用率如CPU、内存使用率等还能看到许多应用层指标比如总请求数、错误响应数、并发连接数、响应时间等等。这些都是你在监控应用运行时非常有帮助的信息而这一切都是PaaS服务自动提供、开箱即用的功能。
而且,基于这些监控的指标,你还能够在云上制定相应的报警规则,当某些指标达到你设定的阈值时,会及时发送警报。这同样是一个非常实用的功能。
**第二个方面是扩展**,也就是底层计算资源和流量需求的匹配。**这里既包含了底层机器配置的垂直扩展,也包含了机器数量层面的水平扩展。**一旦你有调整需求,只需要动动手指发出指令,就可以随时升级相应的机器配置,并无缝切换。
特别是水平扩展的存在它相当于同时包含了我们第7讲中提到的**负载均衡和弹性伸缩**,把它们都一股脑儿集成到了托管服务中。这意味着应用托管服务不是只能对应一台机器,而是能够创建多台机器来承接请求,并会在前端均衡地分发到多个实例上去。这里你同样可以指定自动伸缩的规则,来让应用服务自动地调整实例数量。
下面,我给出了一个实际可用的**Azure应用服务的伸缩规则示例**它设置了CPU使用率的阈值当实际CPU占用超出阈值后服务会自动地增加或减少实例数量。假如我们的fibonodejs服务需要面向公众正式服务的话就可以施加类似的配置。
<img src="https://static001.geekbang.org/resource/image/08/0b/08362e266fdb7124d72ca09ea6ee750b.jpg" alt="">
**第三个方面是集成**这里是指与其他PaaS的集成。这是所有PaaS服务的优势各个服务间可以互相帮助、联合作战应用托管类服务也不例外。比如在监控数据方面它可以和云监控系统进行衔接再比如有些云允许Web应用以目录的形式挂载对象存储中的文件等等。
其中,应用托管类服务还有一项非常重要的集成能力,就是**应用服务与云上DevOps组件和流程的无缝对接**。它意味着应用服务可以作为整个应用生命周期管理的一部分,嵌入到持续集成的流程中去。借助和源代码管理设施的联动,你的应用就可以轻松实现自动化的部署和升级。
比如说我可以把上面node.js应用程序的代码放到Azure Repo或者GitHub这样的代码仓库中之后只要通过满足触发条件的git push操作就能够自动地触发构建并直接更新线上的应用程序。
下图展示了Azure App Service中相关配置的入口
<img src="https://static001.geekbang.org/resource/image/0a/95/0a2ad659a3c306b3421c1ecf650ab195.jpg" alt="">
除了我在上面列举的这三方面的增值服务应用托管服务还有许多有用的特性我没有展开讨论比如说远程调试和诊断、运行环境自动补丁升级、私有网络内的部署、Web防火墙防护等等。这些都是它能够给你带来的强大附加价值。
和其他PaaS服务一样对于应用托管服务**我建议你先充分地查阅文档,建立比较系统全面的认识,然后一定要通过实操,进行探索和实验**,这样你就会有比较深入的理解和感受,便于你作出正确的选型决策。
## 课堂总结与思考
今天我主要给你介绍了云上的应用托管服务这也是最受欢迎的PaaS服务之一。你现在应该已经知道它是用来支撑我们Web应用的一个平台它既包含了应用的基础架构和运行环境也包括了许多增值服务大大方便了我们Web应用搭建和维护过程中的各种典型诉求。
到目前为止,我所说的都是它的优点和长处。那么,你可能会问,**应用托管服务有没有弊端呢?**
我认为,这主要取决于**云服务的封装程度**,以及你**是否有环境定制的需求**。有些人的确不喜欢受限的封装环境觉得难以做一些细节的微调和必要的hack也有一定道理。
好在现代Web托管服务在进行高度封装的同时也都部分地开放了内部运行环境甚至允许你**远程登录**到相应的服务器上去,开展你所需要的改动或排查。这在一定程度上减轻了封装可能带来的“黑盒”问题,比如你可以查看到一些底层操作系统级别的错误日志。
另外你需要注意的一点,就是**价格**。不同云厂商,对于应用托管服务的收费标准都是不同的。至于它们的收费是否合理,你可以与纯虚拟机的搭建来做一个对比。特别是如果你的网站部署规模不小的话,花一些时间来做比较是非常值得的。
不过在进行比较时,你一定不能忘记,应用托管服务能够给你带来的工作效率提升,和维护负担的减轻。因为开发、部署和维护相关的人力和时间成本,都是**总体拥有成本**Total Cost of OwnershipTCO中的一部分。**这也是我在许多时候,会给应用托管服务投上一票的重要原因。**
**这一讲,我留给你的思考讨论题是:**
- Azure应用托管服务还有一个**部署槽**Deployment Slot功能AWS中类似的概念则称为**环境**Environment这同样是一个非常实用的能力。你能说说这个特性是做什么的吗如果你还了解其他好用的特性也欢迎你和大家分享。
- 对于应用托管服务,通过代码打包上传来发布应用,一直是主流的方式,我在前面举例时也采用了这种形式。不过近来,通过**容器**来部署Web应用也成为了云上应用托管服务普遍支持的形式。那你知道后者解决了前者的什么问题吗
好了,今天我们就到这里。如果觉得有帮助,欢迎你把这篇文章分享给你的朋友。我是何恺铎,感谢你的阅读,我们下期再见。

View File

@@ -0,0 +1,124 @@
<audio id="audio" title="12 | 云数据库:高歌猛进的数据库“新贵”" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a1/1f/a1340f2d521911fcc40e3e5717f76a1f.mp3"></audio>
你好,我是何恺铎。
说起数据库相信你一定不会陌生。从开源的MySQL、PostgreSQL到商业级的Oracle、SQL Server再到新兴的各类NoSQL数据库都是我们应用架构中的常客。
而近年来随着云计算的兴起,云数据库作为一支新生力量,一路高歌猛进,打破了数据库市场的原有格局,也进入了越来越多开发者的视野当中。**这类PaaS服务的朴素思想就是将数据库服务搬到云上让用户更方便轻松地使用、管理和维护数据库。**
由于数据库的产品形态天生具有独立性容易标准化封装而且用户侧又往往有运维复杂的痛点。所以这类数据库托管服务一经推出很快就受到了用户的广泛欢迎也当仁不让地成为了云PaaS服务中的杰出代表。你一定要来认识它。
## 云上的关系型数据库
关系型数据库的应用在业界是最普遍的也是云数据库首先进入的领域。这里的先行者同样是AWS早在2009年就发布了RDSRelational Database Service后来其他的厂商也纷纷开始跟进。
RDS其实并不指代单个服务而是一般针对每个数据库引擎都有一个对应的服务比如RDS for MySQL或RDS for PostgreSQL。并且同一种数据库按照不同的版本也有比较严格的分支选项你在创建时就会被要求选定这个版本。
<img src="https://static001.geekbang.org/resource/image/5a/00/5aca6221869d0bc3f9cb24dd61195800.jpg" alt="">
那么RDS类服务和传统关系型数据库有什么区别呢这恐怕是一个绕不开的问题。对于云数据库我想这样回答你**它们既没有区别,又有很大的区别**。
怎么理解这句看似矛盾的话呢?
所谓的**没有区别**,指的是云数据库在外部交互的层面上,保持了和传统“原版”数据库几乎完全一致的编程接口和使用体验。
比如说你针对MySQL编写的SQL代码和应用层连接代码包括你很熟悉和经常会使用的连接管理工具除了要更改连接字符串和参数之外都能够几乎不经修改地在云数据库的MySQL服务上运行。
另外针对某个数据库的某个具体版本云厂商们会把它的功能、内部机制完整地保留下来以求获得最大程度的兼容性。早期比较简单的云数据库实现原理是充分利用云上已经提供的虚拟机、云磁盘等IaaS层面的资源在隔离的环境下进行数据库镜像的安装。而后来技术实力比较强大的厂商还能够做到对数据库源码和模块的深度定制在保证兼容性的前提下进行许多对用户透明的云端适配和优化。
所以云数据库尽管是一个受限的PaaS环境比如它通常无法让你直接访问底层的服务器但在使用体验上和传统数据库是相当一致的。你大可放心之前积累的MySQL和PostgreSQL的知识在RDS上也大都可以适用。在云上你也同样能够找到和安装一些数据库的常用插件来增强PaaS数据库的功能。
而同时我们又说,云数据库和传统数据库**有很大的区别**,这是指在搭建、运维、管理层面,云数据库提升了一个层次,实现了相当程度的智能化和自动化,极大地提升了用户友好度,降低了使用门槛。比如灵活的性能等级调整、详尽的监控体系、攻击防护机制等等,这些许多在传统数据库中需要借助额外工具或产品的功能,在云数据库服务是默认内置,可以开箱即用的。
除了这些基本能力外,我还想着重强调**两个**最具代表性的云上关系型数据库的高级特性。
一个是支持**读写分离**。当并发数量上升时,关系型数据库容易出现性能瓶颈。这时比较有用的办法,就是实现基于多库同步的读写分离。读写分离虽然是常见的架构思路,但你要是不熟悉细节的话,手工配置起来可并没有那么容易。
云数据库就帮我们解决了这个烦恼,你只要在产品后台略加操作,就可以启用这个功能:从创建从库到建立同步,再到读写流量分发,云数据库都能自动完成。看上去高大上的架构实践,在云数据库的帮助下,就轻松地“飞入寻常百姓家”了。
<img src="https://static001.geekbang.org/resource/image/2e/0c/2e8e62947badf5f96e83e2b579a4270c.jpg" alt="">
一个是支持**自动调优**。对于数据库来说,同样和性能有关的一个重要工作,就是性能的调优。以前我们经常需要手动地观测性能瓶颈,找出热点查询,再考虑是否有改进性能的办法。而在现代云数据库中,都自带有性能分析与改进的模块,能够自动地发现性能热点,甚至还能够智能地给出调整建议,比如进行个别语句的调整,甚至添加额外的索引等等。
这个性能分析和自动调优的能力是将生产运行数据和服务内置的AI模型进行了结合是真正的智能化运维毫无疑问这大大增强了云上数据库的竞争力。如果你有线上的云数据库一定不要忘记观察它自动给出的结果和建议很可能会给你带来惊喜和帮助。
给你举个例子下面这张图中是Azure SQL Database自动给出的性能优化建议。你可以看到它建议我在某些表的某些列创建索引还提醒我部分查询应当进行参数化。而且它将各个建议还按照对性能影响程度的高低进行了排序可以说是非常贴心了。
<img src="https://static001.geekbang.org/resource/image/f3/f5/f3c783ff5d908ad0dcc5a05b7fe01ff5.jpg" alt="">
以上的种种特点,一起构成了云上关系型数据库的独特竞争力,也为它赢得了认可。
## 新一代云原生数据库有什么特征?
在通过RDS类关系型数据库服务建立起公众对于云数据库的认知和信任以后聪明的云计算工程师们又开始了新的征程。这次云厂商们不满足于封装现有的数据库而是极具野心地开始构建完全为云设计、能够充分发挥云的特点和优势的数据库。
这就是新一代云原生数据库的由来。
你可能也听说过AWS Aurora、阿里PolarDB、Azure Cosmos DB这几个产品的鼎鼎大名它们正是云原生数据库中的杰出代表。
出于生态发展和降低学习难度的需要绝大多数的云原生数据库仍然保留了SQL等常见接口有的还支持不同SQL方言的选择但除此以外云原生数据库大都进行了全面革新和重新设计有的云会大刀阔斧地改造开源代码有的甚至脱离了现有包袱完全重新构建。
这样的尝试取得了巨大的成功,业界也逐渐形成了一系列不同领域的云原生数据库矩阵,大大拓展了云上数据库的范畴和影响力。
我这里也为你整理了一张表格,按照厂商和云数据库的类型进行了梳理和比较。其中,标红的部分是相当值得你关注的自研云原生数据库。
<img src="https://static001.geekbang.org/resource/image/5d/e1/5d397c48009881559192f918f83906e1.jpg" alt="">
还有其他厂商也有相当出彩的云原生数据库我没有收录到表格中比如腾讯云的CynosDB和华为云的GaussDB等也都是云原生数据库的杰出代表。
**那么,云原生数据库在使用时,有什么优势和特点呢?**
**首先,更强的可扩展性。**
得益于原生设计的计算存储分离架构云原生数据库可以支撑更大规模的数据量突破了传统关系数据库服务的单机单库限制。比如说关系型云原生数据库能够脱离典型的数TB的容量上限达到单库数十TB甚至百TB的级别。这和它单独专门为云设计的存储架构是分不开的。
算力方面也同样如此云原生数据库可以利用云快速地进行水平扩展迅速调整、提升数据库的处理能力。在分布式架构的加持下它相比以前单机数据库的计算查询能力有了成倍的提升。所以云原生数据库往往善于处理大并发的负载可以提供很高的QPS。
**其次,更高的可用性和可靠性。**
和传统RDS服务不同云原生数据库往往默认就是多副本高可用的数据同步、读写分离等高级特性是作为原生机制的一部分天生存在的。像Amazon Aurora中的存储部分就自动包含了分布在3个可用区、多达6份的数据副本。
得益于原生数据同步机制的底层设计云原生数据库还能很方便地支持跨区域的实例复制在进一步增强冗余的同时还能便于就近服务全球用户。比如下图所示就是Azure Cosmos DB跨区域复制的设置页面你可以在这里轻松地指定区域让数据在全球范围流转和同步。
<img src="https://static001.geekbang.org/resource/image/cd/64/cd0f02240150e39e126cc6abf8f7a464.jpg" alt="">
此外,对于**多种数据模型**multi-model的支持也是云原生数据库的一大特征。除了兼容关系型数据库外云厂商还会针对不同的场景进行针对性的研发和优化结合数据库业界最新的流行趋势推出适合不同形态和查询范式的云数据库与NoSQL数据库进行积极竞争。
比如说AWS的键值型数据库DynamoDB和图数据库Neptune都是相应领域中非常优秀的产品。而Azure的Cosmos DB则采用了另外一种做法在一个数据库产品中同时内置了多种数据模型的支持也同样取得了成功。
云原生数据库还往往有**低成本启动**的优势,它能够自然地跟随业务增长。大多数的云原生数据库,**在存储上**不需要你预先设置容量大小,而是会随着存储占用自动扩展;**在计算上**也有部分云数据库开始推出无服务器版本比如AWS的Aurora Serverless它不需要使用固定的计算资源这在面对间歇偶发或者难以预测的工作负载时非常经济实用。
## 云数据库为什么能够不断占领市场?
不论是封装传统关系数据库的RDS类服务还是新一代的云原生数据库都是一经推出就广受欢迎市场占有率不断提高。而像Oracle这样的传统商业数据库近几年却身影落寞在市场上节节败退。这是为什么呢
除了我们前面提到的易用性和丰富功能外,在云上,云厂商还能**端到端地掌控影响一个数据库的设计和性能的所有因素**,可以为它**配备最新、最好的软硬件组合**这也是云数据拥有旺盛生命力的根本原因之一。比如说许多的云数据库都会使用RDMA远程高速访问、NVMe SSD等先进技术。
另外,借助云计算平台,**云数据库拥有非常好的流量入口**。云计算平台让这些新兴的企业级数据库变得触手可及,非常方便你去学习和尝试。这和同样设计精妙,但“养在深闺人未识”的一些企业级数据库形成了鲜明对比。所以现在反过来,老牌企业级数据库需要和云来合作,这就是入口效应所驱使的。
扩展:通过云平台,云数据库还能够更快地推向市场。一旦有了新的特性,可以很快地更新发布,甚至以预览形式在早期就招募用户。这还造就了云数据库的速度优势。
所以你看一个行业的进步和颠覆往往是从一个更高的层面来进行的也就是我们常说的“降维打击”。云数据库之于传统数据库是用完全不同的研发模式、商业模式和产品形态从另一个层面发起了挑战从而具备了竞争优势这就像早年汽车替代了马车一样。这也是为什么Gartner会大胆预测到2023年全球3/4的数据库会跑在云上。
回到我们用户的视角,**你什么时候应该考虑使用云数据库呢?**
可以这样说,云数据库现在已经进入了相当成熟的时期。所以,在云上大多数的场合,我都推荐你使用云数据库,而不是用虚拟机自建数据库。**你更多需要考虑的是,如何在云数据库中选择匹配你需求的型号,同时要注意可迁移性和厂商绑定的问题。**
如果是老的应用迁移或者是其他需要与自建数据库保持高度兼容性的场合你不妨使用经典的RDS服务实现平滑上云如果你的应用场景中数据量大、性能要求高或者是没有历史负担那你可以考虑直接“一步到位”拥抱理念更加先进的云原生数据库。
## 课堂总结与思考
今天,我们主要学习和讨论了云数据库,它完全改变了数据库的产品形态,既大幅减轻了部署维护负担,也让云计算的弹性计算和存储能力得以充分施展。
云上的关系型数据库在保证接口兼容性的同时,还拥有智能化和自动化的特点,能够帮我们进一步地减轻管理压力,以及提出性能优化建议。而全新一代的云原生数据库,更是放开手脚实现了面向云的原生架构,在性能、可用性和可扩展性上,都展现出了巨大优势。
在前面[第9讲](https://time.geekbang.org/column/article/215128)关于PaaS服务的问题回复中许多同学都提到了在使用云数据库我想也正是被它的这些特点所吸引。
这一讲,我还埋下了一个伏笔。在前面的云数据库对比表格中,最后一行对应着云上的**分析型数据库**,这也是云数据库很重要的一个分支。在下一讲讨论云上大数据时,我会更详细地给你介绍。
**今天我留给你课后思考的问题是:**
- 近期某著名的SaaS服务商遭遇了人为数据删除造成了很大损失。在这里我们不深究这个事故的细节但从云数据库的角度你知道如何充分利用云数据库的特性来尽量避免“删库跑路”的事情发生吗
- 分区是传统数据库设计和性能优化的常用手段。对于能够支撑很大数据量级的云原生数据库,分区技术还有没有应用的价值和必要呢?
欢迎给我留言,如果你觉得有收获,也欢迎你把这篇文章分享给你的朋友。谢谢你的阅读,我们下期再见。

View File

@@ -0,0 +1,224 @@
<audio id="audio" title="13 | 云上大数据:云计算遇上大数据,为什么堪称天作之合?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/55/6f/5501ca38e726ff56547f71a212c0936f.mp3"></audio>
你好,我是何恺铎。
今天我们来讨论和学习云计算中的大数据产品与技术,这也是我自己最喜爱的话题之一。
我们都知道,云计算以存储、计算规模和弹性著称,而大数据方面的业务需求,恰恰需要大量的存储,和呼之即来的澎湃算力。所以,云可以说是最适合运行大数据工作负载的平台了。同时,云计算时代数据规模空前扩大,因此大数据也成为了云上最需要解决的重要场景之一。
正因为两者的关系如此紧密,又几乎处于同一个时代,以至于早年有一段时间,很多开发者产生了概念上的混淆,把“云计算”一词当作大数据技术的代称。但事实并非如此,你需要注意甄别。
在当今的技术语言体系中,我们应该这样来理解:**大数据主要是技术手段,是一系列处理海量数据的方法论和技术实现的总称;而云是一种资源和能力的载体,也是一种商业存在,是可以运行大数据负载和应用的平台。**
**举个例子来形容两者的区别:**你可以把云比作一艘航空母舰,是一个大型综合作战平台,而大数据呢,就好比战斗机这个武器门类,在航母上就成了舰载机,依托航母可以达到更大的作战纵深和更强的投递能力。
当大数据和云计算交汇,就自然诞生了**云上的大数据PaaS产品**,它们是云对大数据技术进行了封装和产品化的成果,也正是我们这一讲的主角。
## 云上大数据的体验
和其他PaaS服务类似云上大数据的发展也是从对经典大数据技术的封装开始的。这从一些相关服务的命名中就可以看出来比如AWS早在2009年就发布的大数据服务 **Elastic MapReduce**简称EMR。虽然EMR的服务能力早已不限于MapReduce这个早期技术但这个名字一直被保留了下来这是时间给它打上的烙印。
从技术上讲云上大数据服务其实一直在迅速跟进着社区的发展也在不断地延伸自己的服务范围。从早期的MapReduce到Hive和HBase再到后来异军突起的Spark都逐渐地纳入到了它的服务体系现在可以说已经拓展到了整个Hadoop和开源大数据的生态。
**所以,你在云上能够找到的,不是一个单体的技术组件,而是一系列的大数据服务的组合**。下图就展示了AWS EMR服务的5.29.0版本中,内置支持的丰富组件:
<img src="https://static001.geekbang.org/resource/image/00/32/00d2acfd687db858e281f3f30edd1232.jpg" alt="">
注:从另一个角度来讲,云上大数据服务对开源社区新版本跟进的速度快不快、版本细不细,也是我们评估衡量云服务的一个重要指标。
云上大数据服务最大的特点就是**简便易用,方便管理**。尤其是,我们可以把一个之前可能需要几天时间,来进行安装部署和环境设置的创建集群任务,缩减到短短几分钟,大大降低了我们学习和应用大数据技术的门槛。
说得好不如做得好,接下来我就带你进入**实验环节**来帮助你对大数据服务形成一个直观的认识。我们要使用国际版AWS中的EMR服务运行一段Spark程序来统计小说《双城记》中的单词词频。
首先我们需要创建一个EMR的集群实例。在创建过程中除了像上面那样指定所需要的组件以外最重要的一步是**选择集群的配置**
<img src="https://static001.geekbang.org/resource/image/43/31/43437ea49e14a956418dbe06ddf2b831.jpg" alt="">
我选择了**m5.xlarge**这个型号的虚拟机,作为底层基础设施的机器。细心的你可能还发现了,**用于执行计算任务的机器组,在这里你可以选择价格相当低廉的竞价实例**。这是一个很有用的节省成本的特性,因为很多时候,大数据服务是用于后台离线计算的,我们可以牺牲一些可用性上的要求。
根据向导等集群创建完成进入运行状态后就可以使用了。按照产品提示我们使用SSH就能够成功地连上集群的主节点
```
client@clientVM:~$ ssh -i ~/awskvpair-california-north.pem hadoop@ec2-52-53-xxx-xxx.us-west-1.compute.amazonaws.com
Last login: Sat Feb 15 13:10:50 2020
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
EEEEEEEEEEEEEEEEEEEE MMMMMMMM MMMMMMMM RRRRRRRRRRRRRRR
E::::::::::::::::::E M:::::::M M:::::::M R::::::::::::::R
EE:::::EEEEEEEEE:::E M::::::::M M::::::::M R:::::RRRRRR:::::R
E::::E EEEEE M:::::::::M M:::::::::M RR::::R R::::R
E::::E M::::::M:::M M:::M::::::M R:::R R::::R
E:::::EEEEEEEEEE M:::::M M:::M M:::M M:::::M R:::RRRRRR:::::R
E::::::::::::::E M:::::M M:::M:::M M:::::M R:::::::::::RR
E:::::EEEEEEEEEE M:::::M M:::::M M:::::M R:::RRRRRR::::R
E::::E M:::::M M:::M M:::::M R:::R R::::R
E::::E EEEEE M:::::M MMM M:::::M R:::R R::::R
EE:::::EEEEEEEE::::E M:::::M M:::::M R:::R R::::R
E::::::::::::::::::E M:::::M M:::::M RR::::R R::::R
EEEEEEEEEEEEEEEEEEEE MMMMMMM MMMMMMM RRRRRRR RRRRRR
[hadoop@ip-172-31-1-100 ~]$
```
小提示这时如果你去到EC2的产品界面查询你会看到组成这个集群的所有虚拟机都出现在列表中。这体现了EMR的一种开放性设计也方便用户登录到机器上进行测试、排查甚至定制。
你还记得在[第11讲](https://time.geekbang.org/column/article/217120)中我们《双城记》文本文件在S3存储桶中的位置吧在这里我们使用 **hadoop fs命令**来尝试查看一下:
```
[hadoop@ip-172-31-1-100 ~]$ hadoop fs -ls s3://geektime-hellocloud/
Found 1 items
-rw-rw-rw- 1 hadoop hadoop 804335 2020-02-07 14:45 s3://geektime-hellocloud/ATaleOfTwoCities.txt
```
你看通过使用S3协议头EMR创建的集群是能够自动地和我们的S3对象存储“打通”的相当于把S3挂载为了一个文件系统。这为应用程序的访问和存储数据提供了极大的便利。
接下来,进入到集群为我们安装准备好的 **spark-shell**Spark的交互式命令行工具我们可以直接运行一个基于Spark的经典 **WordCount程序**。(为节约篇幅,这里省去了一些准备性语句和一些打印输出)
```
val book = sc.textFile(&quot;s3://geektime-hellocloud/ATaleOfTwoCities.txt&quot;)
val wordCounts = book.flatMap(l =&gt; l.split(&quot; &quot;)).filter(_.length&gt;0).map(w =&gt; (w, 1)).reduceByKey((a,b) =&gt; a+b)
wordCounts.toDF(&quot;word&quot;, &quot;count&quot;).write.parquet(&quot;s3://geektime-hellocloud/ATaleOfTwoCities-WordCount&quot;)
```
程序顺利执行后,由于我们把计算结果用 **Parquet列存储格式**落地存储到了S3中你可以到S3的相关界面里确认。在这里你可以看到目录已经生成了
<img src="https://static001.geekbang.org/resource/image/39/45/39a6bb14680feb4a5740781a46038145.jpg" alt="">
点击进入目录可以看到其中的Parquet文件说明程序已经生成了结果
<img src="https://static001.geekbang.org/resource/image/60/b4/60b3ffdcfa18174681145a280d37feb4.jpg" alt="">
为了证明结果的正确性我们再使用另外一段Spark脚本来读取刚才的结果文件列出小说中出现频率最高的5个单词及出现次数
```
scala&gt; spark.read.parquet(&quot;s3://geektime-hellocloud/ATaleOfTwoCities-WordCount&quot;).orderBy(desc(&quot;count&quot;)).take(5).foreach(println)
[the,7514]
[and,4745]
[of,4065]
[to,3458]
[a,2825]
```
EMR中再次成功地执行了我们的操作返回了正确的结果我们的实验圆满完成。
在这个实验中,虽然我们用的数据规模比较小,但流程是比较完整的,这也充分体现了云上大数据服务的**易用性**。
## 云上大数据的特点
从刚才的例子中可以看出在使用体验层面云上大数据看上去和你熟悉的大数据技术栈没什么两样。这也是PaaS服务的设计目标之一也就是尽可能地**保证兼容性**。
不过如果我们深入探究,会发现云上大数据服务并不仅仅是做了开源大数据技术的移植和搬运,还是融入了自己的特色,尤其是进一步地**解耦了大数据架构中的计算和存储**。
对于存储端在上面的实验中我们已经看到这种解耦的体现应用程序直接把对象存储服务作为大数据架构的数据源和计算结果的存储位置它可以不需要使用和依赖本地的HDFS文件系统。
当然这并不是AWS的专利事实上几乎所有厂商的云端大数据服务都与对象存储服务进行了深度的集成和适配正好匹配对象存储大容量、高吞吐的特点形成了一对黄金搭档。所以在云上大数据的存储端**对象存储**一般都是优先选择的存储方式。
提醒在一些大数据服务中比如Azure的HDInsight会将对象存储默认挂载为Hadoop的根文件系统/你可以查看fs.defaultFS参数来确认。这样使用起来你就无需存储协议前缀更加接近传统HDFS的体验。
在计算端,你同样可以从解耦中受益。得益于云端的弹性,你可以按需地对大数据集群的规模进行动态的调整,来满足不同计算规模和交付时间的要求。
计算端的另一个常用的最佳实践是,**集群可以动态地创建,做完工作后立刻将集群删除。**
这种**按需启停**的使用方式,让你可以专门为一个目的,甚至一个任务来创建集群,完成后就可以关闭删除。这样不但最大限度地节省了资源,也通过集群专用,解决了不同大数据任务间资源抢占和冲突的问题。要知道,这在云时代之前是不太可能的,因为安装和设置大型集群非常花时间。
一般云上大数据服务还会带有很多**增值服务**,除了常见的性能监控之外,值得一提的是许多云都自带了 **Jupyter Notebook**一种交互式笔记本能让你快速方便地和集群交互。另外有些大厂商还会对大数据框架本身进行改进以进一步增强自己的竞争力。比如说AWS从EMR 5.28版本起就引入了EMR Runtime for Apache Spark这个运行时在实现接口和API兼容性的前提下优化了很多场景下的运行性能。
另外,还有一类大数据服务,更是计算存储解耦的终极体现,那就是**无服务器查询服务**典型的有AWS的Athena和阿里云的Data Lake AnalyticsDLA数据湖分析等。它们甚至不需要你事先申请计算资源而是可以即查即用直接查询对象存储中的数据。然后你也可以“用完即走”不必操心服务的关闭。这类服务在成本上也很独特和EMR这样的按照集群规模和在线时长计费不同它只按照读取扫描的字节数收费非常适合偶发的数据分析需求。
举例来说前面我们已经有处理好的Parquet文件位于geektime-hellocloud存储桶下的WordCount目录。现在我们可以在Athena中创建一个**外部表**指向这个存储地点:
```
CREATE DATABASE athenadb1;
CREATE EXTERNAL TABLE athenadb1.wordcount_s3 (
word string,
count int
) STORED AS PARQUET
LOCATION 's3://geektime-hellocloud/ATaleOfTwoCities-WordCount';
```
然后我们就可以在Athena的交互界面中轻松查询数据了。比如说我们仍然查询小说中频率最高的5个单词也可以通过SELECT语句很快得出结果
<img src="https://static001.geekbang.org/resource/image/ad/97/adcb10a2e3d39438f70c61424c56e597.jpg" alt="">
## 分析型数据库的崛起
除了MapReduce和Spark这样的计算框架在大数据技术领域还有另外一个发展思路和重要分支那就是 **MPP**Massively Parallel Processing数据库现在也常被称为**分析型数据库**。高压缩比的列式存储和分布式并行查询处理是它的两大法宝。
由于和关系型数据库有着千丝万缕的关系分析型数据库乍看上去有些“复古”它使用的是SQL这种声明式的表达。但也正是因为这一点使得它降低了大数据技术的门槛可以让广大熟悉关系型数据库的用户能够用自己习惯的方式来查询和处理大数据。常见的分析型数据库有Greenplum和Teradata等等。
毫无疑问云计算也积极地进入了这一领域甚至唱起了主角。AWS的Redshift、阿里云的AnalyticDB等都是非常优秀的云上分析型数据库。
云上分析型数据库不仅保留了MPP数据库的特点而且云端的生态结合得很好。这里我们继续进行上面的实验使用AWS著名的Redshift服务来实际地说明这一点。
小提示这里我们略过Redshift服务本身创建的过程你可以选择一个最小集群的规模来做实验。
前面我们已经有处理好的Parquet文件位于S3中geektime-hellocloud存储桶下的目录当中。Redshift中同样支持通过外部表的方式来访问S3上的文件这一特性被称为 **Redshift Spectrum**。通过它我们可以很方便地引用不在Redshift自有存储中的数据。
方便起见这里我们直接创建一个指向前面Athena中数据库的外部Schema这样前面在Athena中定义的外部表 **wordcount_s3**就可以被Redshift识别和利用了
```
create external schema athenadb1
from data catalog database 'athenadb1'
iam_role 'arn:aws:iam::5085xxxx8040:role/mySpectrumRole'
```
这里的mySpectrumRole赋予了Redshift访问S3的权限。相关细节在这里不展开了你可以参阅AWS的相关文档。
然后我们就能在Redshift中直接查询wordcount_s3表了。但你也可以把这张外部表的数据拉取过来并落地到Redshift自己的存储中。我们使用 **CTAS语句**来实现这一点:
```
create table wordcount distkey(word) sortkey(count) as
select word, count from spectrum.wordCount_s3;
```
小提示这里我们在创建内部表wordcount时通过 **distkey和sortkey**指定了用于分布和排序的字段充分体现了Redshift的分布式数据库特点。合理地设置这些字段有利于查询性能的提高。
接着就可以查询这张新表了。一般来讲,查询内部表的响应会更快,也能支持更高的并发。
```
client@clientVM:~$ psql -h my-redshift-cluster-1.cwq9zgi6xxxx.us-west-1.redshift.amazonaws.com -d testdb1 -U awsuser -p 5439 -c &quot;select * from wordcount order by count desc limit 5;&quot;
word | count
------+-------
the | 7514
and | 4745
of | 4065
to | 3458
a | 2825
(5 rows)
```
我们还是查询小说中频率最高的5个单词成功地得出了同样结果。值得注意的是我使用了 **psql命令行工具**来进行查询这是一个通用的PostgreSQL的客户端。这证明了Redshift在接口层面和PostgreSQL关系型数据库的兼容性你可以复用相关的工具链和生态。
我们的实验就进行到这里。总得来说呢云上的分析型数据库是基于MPP架构的云原生数据库它非常易用而又性能强大也能够存储和处理很大规模的数据。与云端其他大数据生态的整合更让它如虎添翼。这也是为什么云分析型数据库在云上获得了越来越多的关注也成为了最热门的云上PaaS服务之一。
## 课堂总结与思考
数据是现代应用的核心,也是普遍的需求。云上大数据服务的出现和发展,让我们在云上存储、处理和查询大数据变得简单而高效,它也把云计算的计算存储分离特性,体现得淋漓尽致。所以它们两者呢,真的可以说是天作之合。
云计算落地大数据的形式,既有拿来主义、消化吸收,也有推陈出新、自研改进。这也是我喜欢云的一点,**它没有代替你做技术上的选择,而是同时给你提供了多种各具特色的解决方案**。
在今天的实操环节我们主要是通过AWS的相关服务来进行的。事实上在大数据这个领域各个云厂商都是重兵集结、投入很大现在的产品服务能力也都比较丰富和成熟了。为了便于你了解和比对我这里也用一个表格把不同云的相关服务进行了分类说明
<img src="https://static001.geekbang.org/resource/image/96/30/962906a5d783b32a332757126d475d30.jpg" alt="">
通过以上产品和服务的有机组合你就可以轻松地构建出非常强大的数据仓库和数据湖解决方案了。如果再加上云上的数据管理和数据集成类服务一起配合比如AWS Glue、阿里云DataWorks等那几乎就形成一个更广义、更完整的数据平台了。
**今天我留给你的思考题是:**
- 在Hadoop的黄金时代它最受推崇的一个架构特点就是实现了数据的**就近访问**Data Locality这个特性能够将计算移动到数据所在的地方以获取最高的性能。现在在云上如果使用远端的对象存储是否和这个思想背道而驰了呢背后是什么样的因素在推动这个转变呢
- Hadoop体系中的**Hive**也是一种常用的分布式数据仓库云上大数据服务中一般也都包含了这个组件。那既然有了Hive为什么还要研发Redshift这样的分析型数据库呢它们的应用场景有什么不同
欢迎你在留言区和我互动。如果觉得有收获,也欢迎你把这篇文章分享给你的朋友。感谢阅读,我们下期再见。

View File

@@ -0,0 +1,173 @@
<audio id="audio" title="14 | 云上容器服务从Docker到Kubernetes迎接云原生浪潮" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/5f/14/5f3a11bfa83963c2b5bce63df63d5714.mp3"></audio>
你好,我是何恺铎。
容器毫无疑问是近年来的又一个技术热词。容器化技术的诞生和兴起以及它所催生的微服务架构、DevOps、云原生等技术理念都对软件行业产生了深远的影响。
容器的优点有很多了,完善的封装、便捷的部署、轻量的启动和调度,这些都是容器技术受到欢迎的原因。与编排系统配合后,它能让我们的应用程序容易管理和迭代,即便是再复杂的系统也不在话下。同时呢,容器应用还能做到非常好的可迁移性,环境中只要有符合标准的容器运行时就可以顺利运行。
我相信你对容器其实有一定的了解也知道Docker和Kubernetes分别是容器技术和容器编排的事实标准。甚至不少同学已经有过一些实践的经验。
那么在容器这一讲中,我们主要关心什么问题呢?我认为,你需要重点搞清楚两个问题:
- **容器和云是什么关系呢?**
- **在云上运行容器有哪些方式,它们各自又有什么特点呢?**
让我们顺着容器上云的发展历程,来了解这两个问题的答案。
## 容器上云从Docker到Kubernetes
轻量的容器和富有弹性的云计算,互相之间其实是非常契合的。容器对于运行环境的极强适应性和快速启动的能力,配合云上动态扩展的庞大资源规模,让云端的容器应用可以在短时间内拓展到成千上万个实例。所以,**云可以说是容器应用的最佳载体,容器应用也非常适合在云上运行和扩展。**
其实在Docker技术家喻户晓之前云厂商已经在研究和使用类似容器的技术了因为云本身是多租户的需要**运行环境的隔离性**。所以云本身也是容器技术的用户和受益者只是部分厂商会考虑进行自研未必直接使用Docker而已。
补充:比如说[第11讲](https://time.geekbang.org/column/article/217120)提到过的AWS的Elastic Beanstalk它就使用了类似容器的私有技术以实现Web应用之间的隔离。当然后来呢它也直接支持了Docker容器封装的应用。
而当Docker兴起之后各大公有云都不约而同地开始对外提供容器相关的标准PaaS服务并持续地进行改进。如果我们梳理容器PaaS服务的发展脉络就会发现它经历了一系列的发展阶段。
在初期云上容器平台把Docker容器在云上的**顺畅运行**,作为首要的目标。产品服务的主要目的是帮助用户创建底层虚拟机集群,免去了用户自己手动管理虚拟机的麻烦。然后呢,随着容器应用的复杂化,**编排**逐渐成为了用户最急迫的需求,所以各厂商又纷纷推出和加强容器编排方面的解决方案。
在那个编排框架群雄并起的年代有的厂商选择了多点开花比如微软当时的Azure Container Service可以支持Docker Swarm、Apache MesosDC/OS和Kubernetes等多种编排系统也有的厂商呢选择了自己的编排方式以便更好地和自己其他的云服务集成比如AWS的Elastic Container ServiceECS
当然后来编排框架大战的结果你已经都知道了Kubernetes 最终一统天下成为了事实标准。所以各大厂商又很快地调转方向纷纷为云上Kubernetes的支持加码推出面向Kubernetes的专属服务了比如AWS的Elastic Kubernetes ServiceEKS和Azure的Azure Kubernetes ServiceAKS。阿里云呢同样也逐渐停止了旗下容器服务对Swarm的支持而把发展重点聚焦在容器服务Kubernetes版ACK上。
你看云对容器技术的支持是伴随着容器生态发展而发展的所以很多时候云也是容器生态重要的参与者和推动者。就像Google Cloud中的GKEGoogle Kubernetes Engine由于“根正苗红”也一直是云上Kubernetes服务的标杆之一。
补充如果说之后的技术潮流还有什么变化我想你在云上也一样会看到领域内的最新进展。比如Service Mesh服务网格也有越来越多的云服务正在探索和提供相关的支持与服务。这也是云与时俱进的魅力所在。
所以就现在最新的形势而言如果要容器上云那我想你几乎不用犹豫直接选择各大云上最新的针对Kubernetes的服务即可。
关于Kubernetes本身它是一个非常庞大的技术体系我建议你通过专门的课程来系统学习。但在这里你需要重点了解一下相对于自建Kubernetes集群云上Kubernetes服务的几个独有特点。
首先很多云上的Kubernetes服务**由于云端的多租户特性可以免除你在Master节点方面的开销**。换句话说你只需要创建Worker节点并为之付费就行了。云平台会统一为你提供和托管Master节点降低你的资源和运维成本。
另外,我们都知道**Kubernetes虽然复杂性较高但抽象设计出色能够支持大量灵活的扩展**。所以云厂商在这个方面花了很多功夫能够让很多云平台上的IaaS或PaaS功能组件渗透到Kubernetes的体系中来这样可以让两边有一个更紧密的集成。
比如说,在常用来引导外部流量的**Ingress Controller**入口控制器方面就有AWS的ALB Ingress Controller和Azure的AKS Application Gateway Ingress Controller等基于云上负载均衡器的控制器实现。它们会创建相应的PaaS服务实例来为Kubernetes集群服务。
再比如我们可以在Kubernetes中定义动态存储卷分配策略的StorageClass层面指定使用云端的**块存储服务**来按需创建和挂载持久化存储。下面的配置文件片段注意它的provisioner和parameters字段就展示了一个使用AWS EBS服务来提供的SSD云硬盘的例子。
```
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
```
云和K8s集成的方面还有很多权限认证、日志集成、私有网络等许多方面这里就不一一展开讨论了。这些集成共同构成了K8s在云上运行以及和云全方位融合的坚实保障。
目前AWS还正在积极地研发推进AWS Service Operator for Kubernetes它把S3、RDS等**有状态**的AWS云服务以**自定义资源**的形式纳入到了Kubernetes中。这让我们能够通过使用云服务来扩展Kubernetes的能力并反过来使用Kubernetes来管理这些云资源。我们可以预期类似Service Operator这样的服务未来将会不断走向成熟也能够进一步加快容器和云一体化架构的发展。
从**架构灵活性**的角度来看云上Kubernetes服务还带来了另一个好处**多集群**。
由于建立K8s集群的门槛大大降低了如果业务间的关联较小你是可以考虑为不同的业务单独创建K8s集群的。这样不同的集群之间就有了更好的隔离性也可以单独地扩展。
## 容器镜像服务
容器方面的另一种常见而且又很重要的云服务,就是**容器镜像服务**Container Registry。我们知道容器的镜像是容器化程序封装后的基本单位在云上你肯定需要一个可以存储和管理自己程序镜像的地方就像Docker Hub管理了很多公开镜像一样。
所以在大多数云上都提供了自己的容器镜像服务如AWS的ECR、Azure的ACR等。它们能让你建立私有的镜像仓库支持镜像的推送和拉取还可以进行版本管理等操作。镜像服务虽然看上去简单却是云上容器体系中不可或缺的一环容器的运行肯定要和它打交道。
## 全托管的容器实例服务
上面我们所讨论的容器服务一般还是能够看到虚拟机的在云虚拟机的层面都有相应的集群被创建。这其实是一种半托管的PaaS模式。
**那么,有没有更加方便易用,不用关心底层基础设施的容器服务呢?**
答案是肯定的,这也是近期云计算在容器领域的另一个特点和趋势:**容器实例服务**。常见的有AWS的Fargate、阿里云的弹性容器实例、Azure的Azure Container Instance等等。它们都是“全托管”思想在容器服务上的体现。
如果你只是有一个容器镜像想要尽快地在云上跑起来那么这类服务很可能就是你的最佳选择。因为它简便易行成本低、速度快而且你不需要操心底层的虚机和集群也可以绕开复杂的编排系统只需要关注Pod运行层面的目标就可以了。这是容器实例类云服务很大的卖点尤其对于无状态的应用非常适合。
接下来,我就举一个实际的例子,把[第11讲](https://time.geekbang.org/column/article/217120)中我们计算斐波那契数列的Node.js程序容器化并且把它搬到云上的容器实例服务。我们这里使用 **Azure云上的容器实例**Azure Container Instance来完成这个实验。
首先要把我们之前的Node程序用Docker封装起来相关的Dockerfile如下
```
FROM node:10
WORKDIR /usr/src/app
COPY package.json ./
COPY app.js ./
RUN npm install
ENV PORT=80
EXPOSE 80
CMD [ &quot;node&quot;, &quot;app.js&quot; ]
```
可以用一个简单的打包命令来获得本地的Docker镜像我们就叫它**fiboapp**
```
docker build --rm -f dockerfile -t fiboapp:1.0.0 .
```
然后我们在Azure上新建一个容器注册表也就是前面提到的容器镜像服务。云上会为我们分配一个镜像服务器的域名
<img src="https://static001.geekbang.org/resource/image/06/42/064b51be50d18c5f15fdd6be2db5cc42.jpg" alt="">
接着我们就可以用标准Docker命令登录并且将镜像上传到这个私有的镜像仓库
```
docker login geektimehellocloud.azurecr.io
docker tag fiboapp:1.0.0 geektimehellocloud.azurecr.io/fiboapp:1.0.0
docker push geektimehellocloud.azurecr.io/fiboapp:1.0.0
```
推送完成后,界面上就显示出了这个镜像的信息。
<img src="https://static001.geekbang.org/resource/image/e5/22/e55a8910765424c67bfddf439beaee22.jpg" alt="">
**然后,我们就可以创建一个容器实例,并且指向相关的镜像了:**
<img src="https://static001.geekbang.org/resource/image/5e/d6/5ecabce9b61f7c914d1a95fec6296ad6.jpg" alt="">
随后通过一些特别简单的配置,我们就可以让容器在云上跑起来了。它还贴心地“赠送”给我们一个域名:**fiboapp.japaneast.azurecontainer.io**。
<img src="https://static001.geekbang.org/resource/image/f1/81/f154f6c540df1d8c40788150b3207081.jpg" alt="">
这就大功告成了。我们用curl工具测试一下运行在云容器中的斐波那契服务一切正常
```
client@clientVM:~$ curl http://fiboapp.japaneast.azurecontainer.io/fibo/30
Fibo(30) = 1346269
Computed by wk-caas-3fa7a6b99b-7703b0c1f33ab2xxxxxxxx with private ip 10.244.32.63
```
至此,我们把斐波那契数列应用就成功地迁移到了容器实例服务上。你可以看到,这个服务为我们准备好了容器运行所需的一切环境,我们需要做的,就只是简单地把镜像打包上传而已。
## 课堂总结与思考
从Docker到Kubernetes容器生态不断的发展云原生的技术浪潮已经袭来。不单是我们开发者要学习和拥抱容器技术各个云计算厂商也都想把自己变成运行容器的最佳场所。所以云平台们推出了各种各样的容器相关服务以争夺云上的容器用户。
相信通过今天的介绍,你能够回答这一讲开头提出的两个问题了。**容器和云是相辅相成的,云承载着容器的运行,容器生态也驱动着云的发展。**从运行方式上来看你既可以轻量方便地在云上运行容器也可以在云上Kubernetes服务的帮助下创建集群进行较大规模的编排和部署。
我这里还整理了各大云的容器相关服务名称和缩写,你可以参考下面的表格:
<img src="https://static001.geekbang.org/resource/image/23/eb/2378624e41c7a04c5271b8ffe21d0eeb.jpg" alt="">
不知道你有没有注意,其实容器与云还有一层微妙的关系,那就是容器与厂商力推的一些云服务,**存在一定的竞争和替代关系**。
就像部分PaaS的功能能够使用IaaS来实现一样容器由于它极高的构建自由度和便捷的封装部署机制也可以一定程度地替代部分云上的可复用组件就像我们的实验中用容器完成了[第12讲](https://time.geekbang.org/column/article/218350)中类似效果的应用部署)。而且,它可以作为系统的一部分参与编排,还是避免厂商绑定的“神器”。
从资源编排的角度来看同样如此K8s的各种yaml配置和[第8讲](https://time.geekbang.org/column/article/213805)中提到过的ARM Template和AWS CloudFormation等私有的资源描述方式同样存在能力交集。
这就是为什么你会发现像Google这样在云计算领域相对后发的厂商会更热衷于云原生生态的建设并积极创立和发展CNCFCloud Native Computing Foundation云原生计算基金会这样的组织。因为以厂商中立为特点的云原生阵营若能崛起有助于挑战已经在云计算产品体系中占据优势的老玩家。这是有商业考量的。
当然,不论背后的商业用意如何,业界从碎片化的私有技术到统一的技术标准上面来,这本身就是云原生带来的一种进步,有着非常积极的意义。对我们开发者也是好事情,它帮我们保证了应用的可迁移性。
所以尽管容器一定程度地威胁到了部分云服务,不过云计算再一次体现了技术中立性,云平台们都大大方方地支持和承载了容器的运行,甚至作为重点服务来进行发展。把选择权留给用户,这是云的胸怀所在。
K8s还在快速地发展云上各种IaaS/PaaS服务也是实力雄厚两者亦敌亦友又相互渗透。未来的走向究竟如何十分值得关注让我们拭目以待。
**好了,今天同样留给你两个思考题,欢迎你参与讨论:**
- 后半篇所讲的容器实例类服务与前半篇讲到的云上Kubernetes编排服务其实并不是割裂的关系。通过集成和调度不少云上Kubernetes服务中的Pod能够在容器实例服务中运行。你知道它是通过K8s中什么机制来完成的吗
- 对于最后讨论的容器与云的微妙关系你是怎么看的你觉得未来更多是以K8s为中心、云原生吞噬一切还是云自身的IaaS/PaaS产品体系更为强大K8s只是云中的一个服务呢
这一讲我们就到这里。如果你觉得有收获,欢迎你把这篇文章分享给你的朋友。感谢阅读,我们下期再见。

View File

@@ -0,0 +1,158 @@
<audio id="audio" title="15 | 无服务器计算:追求极致效率的多面手" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ee/79/ee68daa538449cd150f14bc4ce723079.mp3"></audio>
你好,我是何恺铎。
和前一讲提到的容器和云原生一样毫无疑问“无服务器”Serverless是近年来的又一个技术潮流它也是伴随着云计算的兴起而获得了迅猛的发展。这一讲我们就一起来游览和认知无服务器的世界。
## 什么是无服务器计算?
**“无服务器”是云计算中资源抽象的极致体现。**从它的命名上你就可以看出,所谓“无服务器”就是想让用户感觉不到服务器的存在,这是因为有一朵巨大的云在底层进行着支撑。这样你可以完全专注于业务逻辑的编写,而不再关心任何基础设施。
我们在前面课程的讨论中其实已经接触到了一些广义上的无服务器PaaS服务比如[第13讲](https://time.geekbang.org/column/article/218985)中的无服务器查询服务和[第14讲](https://time.geekbang.org/column/article/219793)中的无服务器容器服务。甚至[第9讲](https://time.geekbang.org/column/article/215128)中的对象存储服务,它理论上来说也是符合无服务器特征的,因为你不用关心究竟是什么样的机器和多少机器在背后支撑它。
今天我们要来专门讨论的,是经典的**无服务器计算服务**Serverless Computing。“无服务器”这个名称就是从这种灵活的计算服务起源的。
如果把无服务器计算和容器类服务一起比较的话,这两种云上计算类服务有着共同的优势和特点,比如说,它们都支持细粒度封装和易于大规模扩展。但这两者也有很不一样的地方。
如果说容器是给予了我们很大的定制空间,让你更加容易地按照自己的需要,来进行应用程序的拆分和封装;那么无服务器则是完全屏蔽了计算资源,它是在真正地引导你不再去关心底层环境,你只要遵循标准方式来直接编写业务代码就可以了。
而且在粒度上,无服务器会允许你拆分得更细致、更轻量。你甚至可以把每一个具有独立功能的函数,来作为一个单独的服务进行部署和运行。这也是为什么,在有些云计算的分类方法下,无服务器计算能够单独“开宗立派”,被称为**函数即服务**Function-as-a-ServiceFaaS的原因。
## 你的第一个Serverless应用
百闻不如一见,我们就先直接通过实践来认识一下无服务器计算。
我们还是沿用前面几讲中的计算斐波那契数列的例子因为它简单纯粹的特点其实也非常适合利用无服务器的云函数来进行实现。所以接下来我们就尝试把之前的Node.js程序迁移到无服务器环境上来。
各大云厂商现在都已经推出了各自的无服务器计算服务比如AWS的**Lambda**、阿里云的**函数计算**和微软Azure的**Azure Functions**。在国内的云厂商中,腾讯云也是在无服务器计算上投入较早、产品较为成熟的厂商。今天我们就以**腾讯云的云函数**为例,来运行我们的斐波那契计算服务。
首先,我们来到腾讯云的云函数产品中,在函数服务菜单下选择“新建”。这里需要填写一下函数名称,我们命名为**fibo**然后运行环境选择Node.js。
<img src="https://static001.geekbang.org/resource/image/ec/bb/ecb18cba944045ec9cac9836e92415bb.jpg" alt="">
小提示:这里我们选择的是空白函数模板。你也可以选择系统内置的一些常用模板作为基础,以获得一些上手帮助。
然后,我们简单地填写描述,并选取云函数所运行的角色(角色定义了云函数的一些访问权限,如是否能够访问对象存储等),然后选择“完成”即可创建函数。
<img src="https://static001.geekbang.org/resource/image/07/47/07998dbcdd1b9c6883747144adb94847.jpg" alt="">
函数实例建立后,我们点击进入,来到它的**代码编辑模块**。我们就直接在内置的代码编辑器中进行代码输入,只需要把前几讲的代码略作改动就可以适配云函数了:
<img src="https://static001.geekbang.org/resource/image/f5/75/f51f82c19f46a2d73ce74b1b2255f775.jpg" alt="">
补充这里你可能会惊奇地发现内嵌在云产品界面中的代码在线编辑并不是一个“花瓶”包括智能提示在内的功能其实还相当好用。是的现在云IDE的发展也很迅速在云端直接进行代码编写已经不是痴人说梦了。
图中完整的代码详情我把它贴出来,如下所示:
```
'use strict';
exports.main_handler = (event, context, callback) =&gt; {
var input = parseInt(event.path.split('/').pop());
return `Fibo(${input}) = ${fibo(input)}`;
};
function fibo (n) {
return n &gt; 1 ? fibo(n-1) + fibo(n-2) : 1;
}
```
可以看到,用云函数表达的代码逻辑非常简洁。这里主要是遵循腾讯云的规范,以标准的形式定义和暴露了一个**main_handler方法**,它也就是云函数的执行入口了。
另外,这里你需要注意的是重要的输入参数**event**因为以后具体访问请求的详细信息就会体现在这个event参数的各个字段中。这里我们主要取出**path字段**来获得fibo函数输入参数n的值。
为了让这个云函数能够对外服务,我们接下来就需要为它添加一个**API网关触发器**这样当API被外界访问时这个云函数就会被触发执行并返回结果给网关。
我们可以直接在“触发方式”Tab下选择“**新建API服务**”这样云函数会为我们创建一个配套的API网关实例。
<img src="https://static001.geekbang.org/resource/image/5d/3c/5df006aa40dd14f3d4d8d3cc4b557a3c.jpg" alt="">
API网关是一个独立的PaaS服务它可以和云函数联动使用。**它的作用是为外界访问提供一个端点,并引流到我们的后台计算服务**。这有点类似[第7讲](https://time.geekbang.org/column/article/212714)中使用过的**传输层负载均衡**但API网关是工作在网络的**应用层**它的后端可以连接指向云函数等多种服务。另外API网关还能够提供不少应用层的实用功能比如访问鉴权、限流熔断、版本控制等等。
OK回到我们的实验当中。网关自动建立并和云函数关联后我们就可以请求网关提供的访问路径来触发调用云函数了
```
client@clientVM:~$ curl https://service-8h29d5wp-1258170967.sh.apigw.tencentcs.com/release/fibo/35
&quot;Fibo(35) = 14930352&quot;
```
好,通过上面的测试,我们获得了正确的结果,迁移到云函数的工作就这样轻松地完成了。
你看对于我们的斐波那契数列应用来说是从IaaS篇使用负载均衡和虚拟机搭建到改为使用应用托管服务和容器封装再到这一讲使用无服务器计算。我们所经历的这个过程可以说是从底层到高层从具体到抽象同时相应的实现也越来越简单有一种腾云而上、渐入佳境的感觉。
值得注意的一点在上面创建过程中我们可没有指定任何像CPU核数这样的计算资源因为我们根本不需要操心和感知这些问题。**这是真正的“无服务器”计算,它会根据我们的负载情况,依托云端庞大的规模自动地进行支撑和扩展。**
补充:你不需要为云函数事先划定资源池,但对于单个函数执行单元的计算资源,还是能够进行一定控制的。最常见的是可以根据云函数的需要来选择运行环境的内存大小。
也正因为底层没有固化的资源,无服务器计算的计费机制是与众不同的。它一般会按照**调用次数**和**调用时长**这两个指标来计费。这其实是非常灵活轻量的一种计费方式(部分云厂商计时已经可以精确到毫秒了),从成本上来看尤其适合那些偶尔触发、短时间运行的工作。这会比专门设立一台虚拟机来做同样的事情要划算很多。
另外,现在很多厂商为了鼓励用户去尝试使用无服务器计算,一般也都会提供每月的免费使用额度。对于一些轻量的任务,一个月下来可能都不需要你花一分钱。
**从开发模式的角度来说**如果你对在网页上直接开发Serverless程序的方式还不太习惯或者考虑到这样不方便进行代码管理的话你当然也可以采用本地编辑代码然后上传的方式。而且在本地可以配合厂商支持的IDE工具会让你的无服务器计算的开发体验更加顺滑高效。
举个例子来说对于腾讯云的云函数你可以配合使用Visual Studio Code和腾讯云Serverless插件来实现在本地编写、运行云函数还可以一键和云端进行同步。如下图所示
<img src="https://static001.geekbang.org/resource/image/1a/ce/1a0c636d8a53f4ee116083f274bf02ce.jpg" alt="">
## 为什么说无服务器计算是多面手?
无服务器计算所能做的可远远不止充当快速的Web开发工具。**事件模型**是无服务器的核心编程模型和运行逻辑,所以它非常适合相当广泛的事件驱动开发场景。
事件的起始,要依靠**触发器**。
**云上Serverless服务一般都配套提供了多种多样的触发器**包括API触发器、对象存储触发器、队列触发器等等。比如上面的实验中我们用的就是API触发器它的触发条件为API网关带来的外部Web请求。
较为常用的还有对象存储触发器。比如当用户上传了一个文件,后台程序把它保存到对象存储中,这时相应的无服务器函数会被这个新对象触发,你就能对这个新上传的文件进行必要的处理了。
此外你还值得了解相当实用的定时触发器它可以按照设置的条件周期性触发。通过它和云函数的配合可以在一定程度上代替操作系统中crontab类工具起到的作用也许能帮你节省一台专门触发运行定时任务的虚拟机。
如果说触发器是无服务器计算的上游的话,**那么各种各样的外部交互方式,也让无服务器计算能够对外访问,并向下游输出。**云端的Serverless环境中一般都能够提供一系列重要类库和SDK让你能够在函数内访问其他云服务尤其是像数据库、消息队列这样的外部存储。
比如说你可以改进我们上面的实验代码引入外部Redis作为缓存层在函数中通过对Redis的读写实现数列计算结果的复用。有兴趣的话你可以动手试试看。
补充:无服务器计算本身是无状态的,所有的持久化需求都要借助外部存储来实现,所以经常需要和数据库、对象存储等服务配合,这既是常用手法,也是必然选择。
所以,在云端,一个常见的场景和架构范式是,云函数可以和**消息队列服务**形成一对黄金搭档:当队列中有新的消息进入,队列触发器就会触发云函数,并将消息作为事件参数传递给云函数;然后云函数进行及时处理,处理结果还能够再写入另外一个队列;队列又可以触发下一个云函数。如此层层传递,就可以形成一个流式数据的处理管道,实现数据的实时处理和分发。
无服务器函数们,还可以用另一种方式联合起来,发挥出它更大的威力,这也是现在无服务器业界发展的又一个热点:即允许你按照业务逻辑的控制处理流程,以**工作流**的方式,进行云函数等事件处理单元的组合和编排。
AWS的Step Functions和Azure的Logic Apps以及阿里云的函数工作流都是这种类型的云服务的代表。它们能够让你用**配置文件或图形化**的方式,来设置表达一个复杂的事件处理步骤和逻辑,这是架构在云函数之上的更高层调度框架。
**你可以不用把if/else、顺序执行、并发等调度控制逻辑写在一个臃肿的函数中而是可以分开解耦通过工作流进行组装。**这时每一个Serverless函数作为处理流程的一个环节可以只专注做一件事情。
<img src="https://static001.geekbang.org/resource/image/66/bb/660c502fc5045723e8de000db5faf6bb.jpg" alt="">
工作流服务会来负责事件响应的回收、条件的判断和下一步的触发执行。为了做到这一点,这类服务每次的运行其实都自动维护了一个状态机,来帮助你记录和跟踪状态。
这种通过工作流组合使用云函数的方式进一步拓展了无服务器应用的场景让它能够轻松表达和应对更加复杂的事件处理逻辑。比如通过工作流服务你可以无服务器化你的后端ETL流程。
重要提示:你应当注意这里云函数工作流服务,和前面基于队列的流式处理的区别。工作流服务构建的是**控制流**,定义事件发生的先后次序和条件依赖;而队列流式处理是**数据流**,是数据的传递和流向。
综上所述,在事件机制和工作流服务的加持下,无服务器计算就成为了一个真正的多面手。它在很多环节都能够扮演恰当的角色,除了自己承担的计算任务之外,它还擅长串联很多云端组件,成为系统组件间的胶水层。
## 课堂总结与思考
通过技术上的推陈出新,不断提高研发效率,是业界一个永恒的话题,也值得我们永无止境地努力。无服务器计算技术,以其简洁、易用、高效的特点,通过极致的抽象,完全屏蔽了底层基础设施,让用户可以专注业务逻辑的实现,所以成功脱颖而出,成为了亮眼的新星。
不需要指定硬件配置、完全按需服务,这个产品逻辑说起来简单,但绝非所有的运行环境都可以这样“托大”的,只有云才有可能做到这一点。云端巨大的规模是无服务器函数可以稳定可靠运行的有力保障,无愧于是无服务器诞生和发展的最佳土壤。
你可能想问,**就目前而言,究竟能否在实际生产场景中全面应用无服务器技术?**
我觉得,问题的答案取决于你业务的性质和形态。无服务器计算的技术成熟度已经没有问题,而且它的灵活轻量、便于迭代,都是显而易见的好处,所以非常适合中小公司或创新业务,你不妨大胆一试。比较可行的方式是,前期你可以先小规模使用,摸清它的脾性,如果一切顺利,再逐步加大应用的范围。
当然,说了无服务器计算这么多好话,我们还是要记得恪守冷静客观的原则。所以,你一定不要忽略了**Serverless服务的限制**,毕竟它的本质是受限的环境。**冷启动的延时、内存的限制、云函数的运行时长、并发数上限**等等这些都是你大规模深入应用之前需要评估考虑的问题。虽然云厂商一直在改进这些客观限制在当下对于你的场景是否造成了实质性障碍也是你目前是否选择Serverless计算的一个重要依据。
还有一个你应当小心的地方,在于**应用的可迁移性**。如果我们看看腾讯云的云函数、阿里云的函数计算和AWS的Lambda它们的编写形式虽然大体相同但在接口定义、参数结构、SDK设计等各方面还是会有不少的细节差异。所以除非你对于厂商绑定不敏感否则代码的复用性也会是你不得不考虑的一个因素。
拓展为了解决厂商绑定问题业界也涌现出了像Serverless Framework这样的厂商中立的[第三方技术框架](https://serverless.com/cn/)。通过和多个主流云厂商合作和集成,实现“一套代码,多处运行”,对于无服务器计算来说也不是梦想了。你可以重点关注一下它的后续发展。
有人说,无服务器计算将是继虚拟机、容器之后的第三代通用计算技术,它代表着未来的发展趋势,这个说法不无道理。随着生态的不断成熟,和运行限制的不断改善,无服务器计算技术接下来很可能迎来爆发,前景令人期待。
**今天,我留给你的思考题是:**
- 我们实验中使用的JavaScript是解释型语言非常轻量能够在云IDE中编程并作为云函数直接执行。那么对于Java/C#这样的编译型语言,无服务器计算能够支持吗?
- 从编程模型上来看,云函数一般都支持同步或者异步两种模式,我们实验中使用的是同步模式。那么,异步模式在使用上有什么区别?适合什么样的场景呢?
好了,这一讲就到这里。欢迎你在专栏下方留言,我非常愿意和你一起探讨。如果觉得有收获,也欢迎把这篇文章分享给你的朋友。
感谢阅读,我们下期再见。

View File

@@ -0,0 +1,218 @@
<audio id="audio" title="16 | 云上AI服务云AI能从哪些方面帮助构建智能应用" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/42/3f/4204ea3d0bbffd723128db6df7c4bd3f.mp3"></audio>
你好,我是何恺铎。
欢迎来到我们课程中PaaS篇的最后一讲今天我们来讨论**云上的AI服务**。
近十年以来从机器学习到深度学习AI技术的理论体系和软件生态获得了跨越式的大发展也把很多不可能变成了可能开始深刻地影响着我们的生活。2016年谷歌的AlphaGo和李世石的巅峰对决更是让“人工智能”声名大噪、家喻户晓。
技术的突破催生出了巨大的市场和需求所以各大云计算厂商都非常重视在AI这方面的投入致力于全方位地为人工智能应用赋能。不少云计算品牌在自己的名称中也加上了“智能”二字对于AI的重视程度可见一斑。
我猜你也一定被云AI铺天盖地的广告宣传轰炸过。不过作为开发者我们不能仅仅停留于宣传口径的话术而是要切实地了解云上AI究竟有哪些能力知道怎样让它与应用程序的开发和运行集成。
**那么云AI能从哪些方面帮助我们构建智能应用呢**
可以这样说,**云对于AI的支持是从不同层面以多种形式体现的**。比如在基础设施的层面,我们在[第3讲](https://time.geekbang.org/column/article/208288)中也提到过带有强悍GPU的虚拟机机型已经纷纷登场了。你可以随时用上最新最酷的GPU硬件再配合一些云厂商预置的专用虚拟机镜像比如Azure的Data Science Virtual Machine和AWS的Deep Learning AMI就可以用单机开展一些AI方面的工作了。
当然我们这一讲的重点是AI相关的PaaS服务。它们其实也大致分为两类**一类是各种成熟能力的开放是云厂商已经构建好的现有模型和API另一类则是机器学习的全生命周期管理支撑平台可以帮助你构建属于自己的机器学习模型**。
## 开箱即用的AI服务
我们先来看一看云上可以“拿来即用”的现成AI能力。
各家云都推出了很多不同种类、适合不同场景的内置AI服务比如在Azure云上它们被统称为Azure认知服务Cognitive Services)。这类服务使用起来非常方便,门槛较低,你不需要掌握那些高深的模型构建知识,就可以站在巨人的肩膀上,把这些高大上的能力接入你的应用程序。
这类服务的特点,一般是将**非结构化数据**处理分析的通用需求场景进行了封装和开放。你可以通过云端标准的API和SDK来进行调用一般会按调用次数进行收费。
这里所谓的非结构化数据,指的是图像、视频、语音、文本等包含丰富信息的常见数字化内容。对于这些内容的理解,用传统的程序逻辑很难解决,但这恰好是人工智能的强项,它可以深入分析这些内容,并进行信息提取和转换。
不同的非结构化数据类型对应着不同的人工智能研究领域也对应着相关的各种云上AI服务。
比如**计算机视觉**就擅长处理图形图像它衍生出了人脸识别、物体检测、OCR光学字符识别、安全扫描等很多细分的能力也催生出了多种多样的云上图片分析服务。你可以想象从线下的安防监控和门禁闸机到线上对用户上传图片证照的扫描和处理图片服务的应用场景是非常广泛的。
在近期疫情肆虐的背景下有云厂商还迅速推出了人脸口罩检测的AI服务体现了云厂商的快速应变能力和社会责任感。下面的Java代码片段就展示了通过官方SDK来调用阿里云上**人脸口罩检测API**,这可以判断给定图片中的人物有没有佩戴口罩。
```
//设定账号的AccessKey和地域信息
DefaultProfile profile = DefaultProfile.getProfile(&quot;cn-shanghai&quot;, &quot;&lt;accessKeyId&gt;&quot;, &quot;&lt;accessSecret&gt;&quot;);
IAcsClient client = new DefaultAcsClient(profile);
//构造人脸口罩识别请求
DetectMaskRequest request = new DetectMaskRequest();
request.setRegionId(&quot;cn-shanghai&quot;);
//设置待识别的图片路径
request.setImageURL(&quot;http://yourbucket.oss-cn-shanghai.aliyuncs.com/mytestimage1.jpg&quot;);
//发送请求,获取识别结果
DetectMaskResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
```
这段并不复杂的调用代码也大致说明了使用一个云上AI服务的过程主要就是设置好输入的图片和一些辅助参数然后就能通过Web请求来进行图片分析了。这里我测试了一张网络上路人佩戴口罩的照片执行之后的结果输出如下所示
```
{
&quot;RequestId&quot;: &quot;F24CXXXX-14B6-4E46-AAF8-C11E2E54XXXX&quot;,
&quot;Data&quot;: {
&quot;Mask&quot;: 2,
&quot;FaceProbability&quot;: &quot;0.76107993841171265&quot;
}
}
```
可以看到返回的JSON格式结果中Mask字段的值为2就说明了图片中检测出了人脸并且佩戴了口罩。
补充该API返回值为0代表未检出人脸1代表人脸未佩戴口罩。甚至它还能判断有口罩但没有正确佩戴的场景相应的返回值为3。具体请参见阿里云相关文档。
**自然语言处理**Natural Language ProcessingNLP也是一大类非常热门的AI服务它主要处理的对象是**文本**。借助这方面的云上能力,你能够进行情感判断、命名实体识别、机器翻译等和文本分析有关的复杂功能,非常有助于构建舆情监测、用户评论分析之类的应用程序。
由于语言之间的显著差异在调研这类NLP服务时你要注意它们对于不同语种的具体支持情况。不同厂商的服务可能在语言上面有不同的侧重。一般来说国际厂商会先强化对于英语的支持而国内厂商则通常会很重视处理中文文本的能力。
**语音类智能服务**,同样是一个很受关注的领域,它能识别声音中的内容信息,尤其是把音频转换成文字。还有一种有趣的反向转换服务是**语音合成**,也就是把文本转化为语音,现在也已经是越来越成熟的技术。
比如说AWS技术博客上的大多数文章网页上方基本都有一个音频的版本它的朗读效果非常接近真人但它其实都是用AWS上的Amazon Polly服务来自动生成的。
人工智能服务还可以**处理视频信息**。你可以把视频分解为一帧一帧的图片和一段一段的音频然后通过组合上述的各类服务来进行处理和整合你也可以使用一些直接支持视频内容的云AI服务如AWS Rekognition和阿里云“视频内容分析”来进行视频分析。这些视频分析服务能输出视频中的场景、文本、面孔和各类物体或常见标识你可以用在监控视频分析、用户内容审查等常见的应用场景。
当然,对于每一个细分领域的模型,想要训练成一个成熟准确的智能模型,其实都很不容易,这需要大量的训练数据,和旷日持久的调优与迭代。这些开箱即用的服务如果满足你需求的话,其实是非常简单而有效的选择。你也不需要对模型的内部实现有任何了解,把它放心地交给云厂商就好了。
## 构建你自己的AI模型
前面提到的那些现成的AI服务大多是以**黑盒**的形式来提供能力的。所以,当这些内置服务不能满足我们需求的时候,那就需要我们“自己动手,丰衣足食”了。
我还是拿口罩识别的场景来给你举个例子。假如你不仅需要识别口罩还想进一步判断口罩的类型看它是普通医用口罩还是高防护级别的N95口罩这样的需求恐怕就需要你自己来定制了。
所以说,按照特定的需求来构建自己的定制模型,也是普遍而常见的场景,它也有助于应用端形成自己的特色和核心竞争力。
补充有的时候成本也是一个驱动应用端自行训练模型的因素尤其当业务需求规模大、调用次数相当频繁的时候。这时内置AI服务的按次付费模式就会显得比较昂贵了。
很多的公司都选择了组建自己的团队有针对性地构建自有模型。不过呢在尝试AI工作一段时间以后大家普遍容易遇到的现实问题就是**AI工作的随意性**没有形成体系和章法。比如构建过程的信息分散而混乱核心代码和脚本存储在个人PC上数据和模型得不到妥善的管理甚至会因人员离职导致丢失还有GPU训练资源紧张模型成品部署困难、运行不稳定等等。
当云厂商们发现这些痛点之后就逐渐地开始对云上的机器学习基础设施服务进行布局和投入致力于帮助用户构建自己的模型。现在这一块已经成为了云厂商们新的争夺热点代表性的服务就有AWS的SageMakerAzure的Machine Learning以及阿里云的机器学习平台PAI等。
无论你想要构建哪种模型,包括经典机器学习和深度学习,它们共性的地方在于,都有一个类似的流程和步骤,包括数据准备和标注、模型训练、模型部署等。**云上机器学习服务,它的目标就是非常精准地支撑和赋能这些重要环节,帮助你进行贯穿全生命周期的模型构建和管理。**
所以这类平台非常适合数据科学家和算法工程师日常使用也很适合团队的管理者了解和把控AI研发端的总体情况。
**那么,这类平台究竟是如何服务机器学习任务中的各个主要步骤的呢?**
**首先是数据准备的环节。**
机器学习服务能够让你注册、管理和标注数据集,这些数据集通常位于对象存储当中。尤其是数据标注工作,你应该知道,它是机器学习工作中极为重要的一个步骤,是一切模型构建的基础。可是数据标注又偏偏非常枯燥,而且往往需要多人协作、交叉验证,才能保证标注结果的质量。
好在,机器学习平台为我们集成了数据标注相关的功能,让这件复杂的事情变得十分简单。你可以直接在云提供的网站门户中,来进行数据标注的工作,甚至可以组织团队分配任务,并回收那些正确的结果。这些功能的存在,几乎能够抵得上一个小小的“众包平台”了。
为了给你一个直观的印象我在AWS S3中上传了几张口罩的图片然后用AWS SageMaker的标注模块 **Ground Truth** 创建了一个“标注口罩”的图片标注任务。你可以参考下面这个真实的工作台截图:
<img src="https://static001.geekbang.org/resource/image/38/be/38431ad06f36e144c51efd8eff17cfbe.jpg" alt="">
**其次,是尤为关键的模型训练环节。**
在这个环节,机器学习平台一般都提供了许多内置的常见机器学习和深度学习算法,分别适用于不同的应用场景。你可以基于这些内置算法,使用自有数据训练出符合你需要的模型。
你可以在平台提供的类似Jupyter Notebook的开发环境中撰写编程脚本来控制模型选择、参数配置和训练数据输入等在模型训练中一系列的关键逻辑和设置。这些工作大多是使用Python语言厂商也一般会提供相应的Python SDK来帮助你和云上机器学习平台交互。
补充:也有部分厂商提供了可视化的环境,允许你在画布上拖拉控件和使用流程图的方式来训练模型,比较适合机器学习的初学者和没有编程背景的用户。
接下来,我就以**AWS SageMaker**为例,带你看下如何调用内置的算法来进行模型训练。
```
from sagemaker.amazon.amazon_estimator import get_image_uri
# 获取内置算法对应的镜像
training_image = get_image_uri(region_name, 'builtin-algorithm-name')
# 创建Estimator实例
estimator = sagemaker.estimator.Estimator(training_image,
role,
train_instance_count=1,
train_instance_type='ml.c4.xlarge',
output_path=s3_output_location,
sagemaker_session=sess)
# 设置模型训练的超参数
estimator.set_hyperparamters(...)
# 将训练数据喂送给模型进行训练
estimator.fit('s3://bucket/path/to/training/data')
```
即使你是第一次接触使用SageMaker这样的工具也很容易理解上面代码片段中语句的含义。其中SageMaker的核心概念**Estimator******就是模型生命周期管理的主要抓手,你可以用它进行高层的语义操作,比如算法的选择、超参数的设置、训练数据的输入等等。这些高层次的方法使用起来清晰明了,它们会为你代劳与云平台底层资源的交互。
注意:为了便于讲解说明以及突出重点,我对脚本中调用参数等处进行了适当简化。下面的举例同样如此。实际使用时,你可以根据具体使用的模型类型,参考云厂商的详细文档。
除了可以使用厂商内置的机器学习算法,**云上AI平台也兼容开源的机器学习和深度学习框架**比如著名的Scikit-learn、TensorFlow、PyTorch、MXNet等等。使用开源机器学习框架能够让你彻底地控制你的底层算法和模型结构也便于相关代码在不同平台的复用。
你也许会很好奇,**像SageMaker这样的厂商自有机器学习体系它是怎么集成和支持这些开源框架的呢**我们来观察下面的代码示例:
```
from sagemaker.tensorflow import TensorFlow
tf_estimator = TensorFlow(entry_point='tf-train.py',
role=role,
train_instance_count=2,
train_instance_type='ml.p2.xlarge',
framework_version='2.1.0',
py_version='py3',
distributions={'parameter_server': {'enabled': True}}))
tf_estimator.fit('s3://bucket/path/to/training/data')
```
可以看到,和前面的自有算法一样,这里同样使用了**Estimator**的概念来管理和控制训练过程。不过你要注意一下这里的TensorFlow类它不是指TensorFlow框架本身而是一个在SageMaker中用于管理封装TensorFlow相关模型的Estimator。**秘密包含在作为entry_point参数的脚本文件tf-train.py中在这个脚本里你才会编写真正的TensorFlow代码。**
小提示当然为了能在SageMaker环境中顺利运行你的TensorFlow脚本需要遵循一些AWS规定的标准比如环境变量设置、输入输出的路径和格式等。
所以说SageMaker是通过将控制层和算法实现层分离的方式来同时支持自有算法和开源框架的。无论你是使用什么算法和模型它的上层仍然是统一使用Estimator的接口实现了对具体算法的抽象。
**另外值得注意的是**云上机器学习平台能够很容易地让你调动云上的计算资源比如通过上面的train_instance_type和train_instance_count参数不需要我们手动来进行创建和维护。尤其是那些支持分布式训练的模型算法在云端充足的CPU/GPU资源和弹性分配机制的加持下你可以很容易地对模型训练进行充分的并行化这大大缩短了模型训练所需的时间。
**最后,则是模型发布和部署的环节**,也就是我们需要把训练完成的模型进行保存和管理,以及进行线上的发布和运行,有时这也被称为**推理**Inference阶段。
同样借助上面的Estimator对象这里我们只要简单地调用一下 **deploy方法**,就可以把训练好的模型部署到生产环境中,并通过新生成的 **predictor对象**来进行模型调用了,如下所示:
```
# 将前面fit方法生成的模型部署到SageMaker端点上进行服务
predictor = estimator.deploy(initial_instance_count=1, instance_type='ml.p2.xlarge')
# 通过predict方法进行模型调用
response = predictor.predict(data)
```
甚至对于大批量数据的场景,你还可以借助**transformer机制**,离线地进行模型的批量调用。
```
transformer = estimator.transformer(instance_count=1, instance_type='ml.p2.xlarge')
# 批量调用数据
transformer.transform('s3://my-bucket/batch-transform-input')
transformer.wait()
# 随后可以从transformer.output_path中下载结果数据
```
你看SageMaker的这些功能还是很贴心的它大大地简化了模型的部署和推理调用相当程度地解决了模型开发者未必熟悉的Web服务的工程性问题。
好了对于机器学习基础设施服务我们就讨论到这里。你可以通过下面的SageMaker架构流程图来加深对这个支撑体系的印象。这一类云服务在你构建自有模型时能帮你提供**一站式的解决方案**,能在多个核心环节给予你鼎力的支持。
<img src="https://static001.geekbang.org/resource/image/de/76/defd655d3a7650a1008d86f3d4cce276.jpg" alt="">
## 课堂总结与思考
当今世界的现代应用程序如果其中没有一点AI的元素恐怕都会不好意思发布了。与这样的趋势相匹配云平台都希望成为构建和运行新一代智能应用程序的最佳平台。
你可以根据自己的需求直接使用云上AI服务中琳琅满目的内置模型也可以利用云上机器学习平台来高效地构建你自己的智能模型。云上AI平台还提供了很好的管理手段来保存和使用公司的数据和模型资产让你的AI工作朝着规范化、工程化的方向发展。
AI技术博大精深你当然需要通过专门的课程去系统学习。而我们这一讲的价值在于主要关注了云对于AI任务在不同层面的结合点和支撑点包括模型、数据、算法、计算资源、部署推理等等。通过今天的介绍希望你在云上实践时能够知道如何按图索骥在某个细分的AI场景进行深入的尝试。期待你的下一个智能应用。
最后作为惯例,我们还是要谈一谈这里的风险,主要仍旧是**厂商绑定的问题**。如果你比较关注可迁移性那么在使用云上AI服务时你就需要注意甄别哪些是云的自有生态哪些是开源组件。当然云厂商其实也在不断升级努力地让云上AI服务从完全内置的黑盒到逐渐走向开放和兼容。最终让每一个环节能够拆开单独使用并且互相解耦这是未来的一个发展趋势。
补充:我们也不要“谈绑色变”,绑定是正常的商业选择,也常会给用户带来效率的提升。云计算的很多服务和开源世界的若即若离,其本质是在生态发展和客户黏性,在技术普惠和商业利益中,不断进行着博弈和平衡。
**这一讲,我留给你的课后问题是:**
- 作为模型构建的重要组成部分还有一个“调参”Hyperparameter Tuning的阶段它也是一件困难而又麻烦的事情。你知道调参具体是指什么意思吗在这方面云上AI服务能够提供帮助吗
- 前面我们谈到了可迁移性的问题它不仅是指代码也包括训练好的模型。那么外部训练好的模型能够放置到云上AI服务中吗在云上训练好的模型又能不能取下来放到本地环境中运行呢
欢迎你给我留言和参与讨论。如果你觉得今天的内容有帮助,也欢迎把这篇文章分享给你的朋友。
好了至此我们PaaS篇的内容就全部结束了。我是何恺铎感谢你的阅读和陪伴。我还有许多想说的话让我们在结束语中再见。