《如何使用pipeline及S3作缓存的具体应用》来自“英方周末第四期”

 

导语

作为一名程序员,你一定不会对Pipeline感到陌生,Pipeline最早被使用在Unix操作系统中。Pipeline的出现仍然是为了很好的解决软件设计中老生常谈的设计目标——高内聚,低耦合。它以一种“链式模型”来串接不同的程序或者不同的组件,让它们组成一条直线的工作流。给定一个完整的输入,再经过各个组件的先后协同处理,最终得到唯一的输出。不无夸张的说,Pipeline是Unix创造的一个伟大的发明。

 

 

 

basic infrastructure patterns

作者:learning with scripting

翻译:张洁  王晨

校正:J 先生  M 先生

原文链接:http://www.scriptcrafty.com/basic-infrastructure-patterns/

 

 

当你在做软件设计或架构的过程中,有一些基本架构会被反复提及。

 

Pieline

 

Pipeline几乎是一切的基石。设计一个适当的Pipeline需要有明确的输入并产生明确的输出,即使在某处停滞不前时,也能告诉你哪个模块出了问题。Pipeline的特征是它的复合性质。如果你曾经玩过函数式语言,那么对此应该并不奇怪,因为从数学意义上来讲,Pipeline本身就是一个函数的化身。

 

建立一个有用的Pipeline非常简单。大部分时间我采用bash就能完成,有时候如果bash做不了,我就会采用Ruby和rake。你可以选择你最喜欢的语言和除grunt、gulp或是broccoli以外的工具。如果你坚持使用Javascript可以利用类似jake这种JavaScript构建工具。下面将会介绍一些可增强Pipeline功能性的其他基本架构。

 

散列缓存

 

如果你知道什么是hashmap,那么这种模型就是将hashmap应用于文件系统中,从而管理定义的集合,如节点模块,优化构建/测试Pipeline,非常方便。

 

现代web应用程序与前端和后端有着大量的依赖性。幸运的是现代软件开发的最佳实践正在鼓励这些依赖性。Ruby有bundler和Gemfile、Gemfile.lock。节点有npm、packages.json、npm-shrinkwrap.json,Python有pip、requirements.txt,Elixir有mix、mix.exs等。这些标志性特征明确地描述了应用程序的依赖性。

 

你可能会想到,在这种情况下,缓存一次性操作的意义何在。好吧,在使用Jenkins或其他CI环境构建架构时,你可能没有足够的研发精力,而且做起来也会吃力而不讨好,因为很多情形都有可能发生,让你措手不及,甚至让你的Pipeline一团糟。因而,将事情留在身边慢慢完成或许并不可能(如workerpools采用spot instances)。目前我还没见过哪个缓存管理可以正常运行,从而能够避免因堵塞、tmp或$ {HOME}引发不必要的磁盘填满等问题。理想条件下达到这一目标非常容易,但现实情况却通常比较棘手。最简单的做法就是不依赖软件包管理器提供的缓存管理。

 

我使用到的技巧是为本地化depends-on安装目录(前提是包管理器没有这样做的),将描述depends-on(Gemfile、lock、npm-shrinkwrap.json等等)的文件散列到存储设备上,然后生成tar.xz文件,其中包括所有的已安装的depends-on(由Gemfile、lock、npm-shrinkwrap.json等这些依赖集的描述散列文件命名)。一旦tar.xz生成,我就可以把它放在本地或在S3,留待下次散列文件匹配时再用。这意味着本地即使没有了当地环境,我也无需通过网络去重新下载我的depends-on(但如果tar.xz在S3中,我就仍然需要去下载,只是我的工作量则少了很多),只需解压tar.xz文件,depends-on就能正常运行。我可能还需要调用构建脚本更改一些东西,因为安装包会将各种文件安装到除项目目录之外的其他地方,但这通常很容易修复。

 

Pseudo-bash基础示例

之所以做这项工作是因为手头的一个项目,它的一群节点模块分散在几个子文件夹中,而因为网络问题,构建/测试失败往往少有人提及。现在还有其他地方失败了,但至少不是因为npm。同样的原则也适用于其他包的管理系统,但不同于npm的情况,你可能需要细读一些文档,从而在安装之前准确找出模块存储的位置。

 

Retries and Fallbacks

所以即使输入和输出Pipeline定义明确,你也需要缓存各种人为产物,这样就可以省去很多多余的工作,但这并不意味着你就拥了有一个不会出错的Pipeline。做完以上事情,你几乎可以完成目标的90%,而剩下10%的工作应该非常少,这时人工干预代价也就并不高了。

 

假设在Pipeline从S3中抓取东西,例如包含很多节点模块的tar.xz,但由于这一操作需要网络,而网络会很有可能失败,如果想让它更为稳定,最简单的事就是多试几次。

 

上面的代码有效,但要让其更可靠,就还有一些工作要做。

 

如果这是一个持续的环境,你可以控制或至少有足够的控制权,以确保一些文件夹和文件逗留一段时间,而不是每次都去查看S3,你应该首先检查本地和重新利用上任何已经存在的文件(假设在本地删除了一些文件,又从S3下载东西)。

这是一步非常好的操作,因为如果我们已经有东西在本地,我们就不必担心网络问题了。但还有一件事需要处理,以防我们不知道从本地或S3哪儿去获取文件。

 

这是相当不错的了。我们有重试和回退机制以防事情失败,而且我们尽可能地避免了不必要的工作。

 

Pipeline in a Loop

 

在控制理论里有稳定和不稳定反馈循环的概念。为服务器设计控制回路循环时,必须尽可能安全稳定(这基本上意味着即便离开系统,当系统故障时,也会发出警报)。AWS中的Auto-scaling就是一个控制机制示例,虽然我不知道要做到稳定循环,它会提供哪些具体数据。

 

笔者目前就在研究这样一个循环,控制一大片的Jenkins worker,我们正在研究一个非常基本的设置,降低工作成本。工作量每天的每个时段都会发生变化,没有理由10个程序能完成的工作去设计100个程序来做。

 

Pseudo-Ruby示例

 

 

希望你领会到了其中要点。基本状态同步一个loop中的Pipeline,操作如下:

 

最后,就是基本的部署模式了,你懂的。

 

 

—end—

 

「英方周末」以“线上与线下相结合、倾听与分享相结合”为特色;以“解析知识、传递知识”为己责;将预见性、知识性和趣味性熔于一炉,寓技术、思想于谈天说地之中。每周末,英方周末与你不见不散。英方周末所有内容版权为上海英方软件股份有限公司所有。

 

 

关于英方

 

英方是一家专注于容灾及业务高可用领域的专业技术厂商。公司以保证企业业务连续性为首要目标,以实时数据复制、持续数据保护技术,为各类企业在物理、虚拟或云计算平台的关键业务提供连续保护及快速恢复。

英方云(i2yun.com)是英方旗下企业业务连续性云服务平台,基于互联网为企业用户提供迁移、灾备和高可用等服务。让用户数据和业务在私有云、公有云或者混合云上实现自由的流动、保护、应用和分享。

 

英方,让世界早有准备

posted @ 2016-05-16 10:38  程小微  阅读(134)  评论(0)    收藏  举报