文章: Etsy工程师Sam Haskins谈代码部署,监控与故障处理

标签: 文章 etsy 工程师 | 发表时间:2013-03-20 22:20 | 作者:
出处:http://pipes.yahoo.com/pipes/pipe.info?_id=10560380f804c7341f042a2b8a03e117

在本次访谈中,Sam Haskins分享了他在Etsy做DevOps的经验。Etsy使用Git做代码管理,平均每天提交的更新数量在30次左右,有时甚至达到70个。在如此高频率提交代码的情况下,他们如何进行代码审查?如何在每次更新之后监控系统性能?如何处理故障?下面,Sam将一一解答。

Sam Haskins目前属于Etsy的核心平台团队,该团队一共有10~15人,整体负责服务器及系统层与应用层的接口,为上层开发特性的工程师们提供服务。Sam于2010年中加入Etsy,他现在主要负责数据库接入层,也在web框架上做一些东西。核心平台团队的其他成员还负责开发图片存储系统、异步任务管理等功能。Sam毕业于卡内基梅隆大学的数学系。

代码部署和审计

InfoQ:第一个问题是关于部署系统的。你们使用哪些工具?

Sam:我们使用Git做代码版本管理,使用Deployinator(我们为自己开发的一个工具)从Git中拿东西出来,并把它放到所有的服务器上。基本上就是文件复制工作,没有什么特别的。另外,我们使用Chef做配置管理。就这些了。实际上我们用GitHub。我们有一个内部的GitHub来管理代码。

关于代码审计流程,实际上我们没有很多正式的检查。只要你的代码能编译,能运行,你就可以放到代码库上,不需要审计。但是,我们鼓励大家做代码复查,而且大家经常这么做。代码复查通常是这样的——你只要把你的补丁发给别人看,他们看过后给你一些点评。大多数人在推送代码到代码库前都会这么做。

InfoQ:有QA吗?

Sam: 没有。我们没有传统意义上的QA。因为我们每次的提交都很小,所以发现哪些代码破坏了系统通常是相当容易的。当然,也有一些人的工作有点儿像QA,他们的工作就是试着破坏我们的系统,然后让我们知道哪些东西坏了。我们部署做得很多,一天部署50次挺平常的,有时候会更多。在部署前后做全面的测试是不可能的,根本没有足够的时间。但是我们有自动化测试,和代码审查等等,而且我们每次的变更都很小,所以,我们认为我们并不需要有一个大规模的正式的QA过程。

InfoQ:那么,当你做更新时,你如何做环境控制,保证代码安全?

Sam:对于我们的工具Deployinator来说,只要你点一下按钮,它所做的就是从Git中拿出东西,并把它分发下去,仅此而已。

InfoQ:你们部署的是源代码,而不是打包后的二进制文件?

Sam:是的,我们不打包。它就是把它们放到web服务器的某个目录下之类的,没有什么太复杂的。我们不做太复杂的事儿。

非常简单,只要几分钟就运行完了。 正是因为很容易,所以我们才能部署这么多次。

InfoQ:那么一天50次是比较典型的部署频率吗?

Sam:差不多。今年的平均值可能是30或33次,算上星期六和星期日。但通常星期六和星期日我们什么也不做。我想,最多的时候,我们可能在一天里我们最多部署60或者70次,少的时候也有二、三十次。的确很多,但这也是我们改变了写代码的方式,让它变成合理的事情了。假如我们每次都做很大的变更,这么做可能就不行啦,一定会变成一种灾难。正是因为我们每次只做很小的改更,所以这种方式才能行。

部署的流程与健康监控

InfoQ:由于你们每天部署这么多次,那么你们通常在一天中的什么时间部署?你是部署后,观察几分钟,然后再部署另一次吗?

Sam:是的,我们有很多度量项,可能成千上万吧。所以 每次部署后,除了要监控你的变更是否起作用了,我们还有一个标准的部署指示仪表盘,你需要关注。那上面有一堆图表,你要看着它,并确保仪表盘上的指标没有异常。

我们还有一个工具,用来读实时日志,你也要看看那个东西。假如有些东西不正常,那你就需要修复它。但只需要几分钟就行,通常是一两分钟。但我要看更多一些的图表数据。 只要没有什么问题出现,并且你认为你的修改正常工作了,那就轮到下一组啦。

InfoQ:当部署时,你是先把它部署到测试环境上吗?

Sam:有一个前提,在你部署之前,你已经自行测试过它了,所以我们是直接部署的。不过,的确也可以说我们已经在测试环境上部署过了,因为我们的试运行环境也是我们的生产环境,是同一个环境,只是版本高一点儿,而且用户不可能访问到这些服务器,只有我们才能访问。

因此,当部署时,首先会放到试运行环境,然后CI(持续集成服务器)会运行测试,是单元测试。顺便说一下,我们使用的是Jenkins。同时,你可以访问试运行环境,Jenkins运行一系列的测试。之后,一旦推送代码的人认为试运行环境上的功能没有问题,他们已经测试过他们的变更,并认为这些变更运行正确的话,那么只是Jenkins运行完(通常总共需要5分钟),就可以推送到生产环境了。

InfoQ:你在这里提到的生产环境,是指所有的机器吗?

Sam:是的,是所有的机器。

这个工具只有两个按钮,一个指向试运行环境,另一个就指向生产环境。

InfoQ:那是否根据服务的不同,分成了不同的集群呢?比如一种服务,使用一类集群?

Sam:算是吧。所有的部署都是同样的软件栈。 同样的web软件栈。但我们的确有搜索专用的软件栈和图片存储专用的软件栈,但那些软件栈也与它相关。我们并没有太多的Service。我们只有一个代码库,所以它也非常大,大约2GB吧。但绝大部分都用同一个软件栈。

因些,当做部署时,先是web服务器,然后是API服务器。我们有内部的支持系统,异步任务,Gearman,以及类似于运行后台任务(Cron)的机器和相关设施,所有这些都是一次完成的。

InfoQ:那么你会根据它们的重要程度做分别推送吗?你要知道,有些部署可能会对用户产生很大的影响。

Sam:我们非常喜欢现在这种工作方式的原因,就是因为这种方式决定了你说的这种情况不会经常发生。如果真有什么事情非常重要的话,那么你可以自己做部署,并确保更顺利。但是,通常来说,我们更喜欢鼓励大家以一种好的方式工作,以避免这种事情的发生。

InfoQ:也就是说,避免一次性做很大的变更,是吗?

Sam:是这样的。

InfoQ:所以,你们总是提交很小的变更?

Sam:当我们发布新功能时,我们会使用配置文件对功能进行控制,比如关闭这个功能,打开那个功能,因为很难一点儿一点儿的发布一个新功能。当需要发布某个功能时,我们再把开关打开。这种方法使得发布并不需要太多的精力,并且比较安全,我们可以做到只在公司内部发布,我们也可以做到只发布给属于beta群组中的用户,也能做到每次向百分之多少的用户发布。

所以当做了一点儿改动时,我们常常只发布给1%的用户,以验证没有破坏其它功能,然后再逐步发布给所有的用户,而不是一次性发布。如果发布的是一个新特性,我们更多的时候只是把开关打开。但有时我们只会将特性发布给一部分用户,以便观察用户在接下来的几天里是如何使用它的。我们会持续关注。

InfoQ:是不是说,beta用户会被导向某个特定的集群?

Sam:节点都是一样的。我们只是在运行时检测,比如通过用户的user ID。

InfoQ:你们是使用自己构建的系统做这件事呢?还是用其它的什么工具?

Sam:我们自己写的代码。它原来的版本是开源的,而这个新版本要比原来那个版本好得太多了,但是还没有发布,不过即将发布了。

这个项目的名字不怎么好,好像是叫做Feature Flags之类的。它在我们Github的主页里。

这就引出了另一个话题,也是我们开发中使用的方法。我们并不使用Git中的分支。大家并不会在一个分支上工作很长时间。通常一个分支的生命周期很短,很快就会把代码部署了。

有关故障

InfoQ:你们是如何处理故障的?

Sam:因为大家都被培训过如何看图表,如何查日志。通常我们发现故障是非常非常快的,因为一直有人在查看我们的那些度量项,这些度量项的确非常多。大家都非常了解这些度量项正常是应该是什么样子的。

InfoQ:那是一分钟查看一次,还是一秒钟?

Sam:我们使用Nagios做自动化的检查。每个检查的时间周期不同。有一些非常非常频繁,而有一些则不是。我们不但有很多这种Nagios做的自动化检查,还有一些人来看图表,以及对应的模式。这种图表的更新通常是一秒钟。

因为一直在不停地部署代码,所以不得不时刻查看那些图表。既然经常看着那些图表,那么对我们来说,快速地发现问题也就不是什么难事啦,因为一直不停地在做这件事,所以也就做得好啦。

InfoQ:听上去感觉好像很依赖人肉啊?

Sam:是这样的。但我们也有像Nagios这样的工具来检查那些可能出错的地方。不能及时捕获故障的情况很少,几乎总是能马上发现问题。那些无法用Nagios无法检查的东西在半夜也不会出问题,因为没人会在大家都睡觉时去部署代码。那些出错的地方通常都是在系统级别上,而通常都是由Nagios来监控的。在白天我们工作时,因为有新的部署,这些地方才有可能出错。但这时会有人看着,因为他们正在部署代码。所以那些很难用计算机去监控的东西在晚上不会出错。

InfoQ:那么,当出现了一个问题时,你们会采取什么样的措施?

Sam:如果某次部署严重地影响了网站,我们所做的就是要求大家别再推送代码,并让整个生产线停下来,然后无论是谁发现的问题,他都要马上开始分析,尝试找出是哪里出的错。我们都可以访问那些日志和图表数据。当我们确定哪个特性出了问题时,我们会联系那些做这个特性的人或可能知道这个特性的人。通常情况下,如果与部署有关的话,相关的部署人员都已经就位了,因为我们时刻使用IRC Chat。

大家都在这个聊天室中,所以如果是部署问题,正在做部署和观察监控的人就知道哪里出了错,很可以也已经知道如何修复它了,因为每次部署只做了很小的改动,所以他们可以将代码回滚,部署原来的那个版本。但对于比较小的缺陷,我们更倾向于推送新的修复代码,而不是回滚。就是直接修复好缺陷,再次部署。

InfoQ:那会花的时间较长吧。

Sam:是的。所以如果只是小问题,能很快修复,那就提交并部署新的代码。因为即使回滚的话,你也要再一次推送代码,总共也需要大约十分钟的时间。因为先要上试运行环境,然后才是生产环境。所以无论你是提交修复,还是回滚,花的时间差不多。如果你多花五分钟 能够正确地修复问题,其实并不赖,甚至可能更好。

所以,通常我们会这么做。如果问题很严重,显然我们会先回滚,然后再找问题的根本原因。然而经常遇到的情况是你并不能完全确定回滚就是你想要的结果,所以与盲目回滚相比,我们更多的是试图找到真正的问题所在。

InfoQ:向前修复通常是以什么样的方式进行的呢?

Sam:大多数在部署时遇到的问题并不会影响整个网站,它们只是会影响其中的一小部分。如果是向前修复的话,当你在修复这个问题时,其他人还可以继续推送他们的代码,继续做他们原来做的事情。但是,显然我们做这种决定要基于故障的严重程度。

InfoQ:修复不好,怎么办?

Sam:如果不立即修复的话,就要开始做回滚操作。

InfoQ:比如说,花了十分钟以后,你也不能修复故障怎么办呢?

Sam:我们并没有那种严格的用于快速决策的规则。但是如果大家不得不在那里等待你修复你的问题,那通常说明什么地方出了问题,其他人就不会部署代码。如果你耽误其他人部署代码太长时间的话,那么我们的做法是采取最快的方式,无论哪种方式都行,让大家可以部署代码。所以十分钟过去了你还没有找到问题,但你认为回滚会让工作回到正轨上的话,当然你就要先回滚,然后在你自己的机器上继续找问题。

InfoQ:能讲一下新近的一次故障吗?

Sam:好。比较典型的情况是,我们只会遇到一些很小的问题。比如,有人正在修改一个页面,而此时我们网站上的一个卖家正在修改他有多少东西可以卖。我并不能说这是一个现在正在发生的案例,但是,它的确与我们看到的小故障类似。这个开发人员修改的恰好是这个页面,那么卖家可能就会看到一个错误,但这并不会耽误大家在网站上卖东西。这时我们会认为,问题并不大。这个开发人员去查看一下,然后修复它就行了。通常由于变更很小,所以直接修复,然后推送部署就行了。但要强调的是,如果问题比较严重,那就会回滚。

最近就发生了一个非常严重的问题:我们在数据库中使用完整的IDs,而这些IDs不是自增的。我们没有让数据库来做这种ID自增,因为我们所有的数据库都是双主方式(two masters)的,即master-master。所以无法使用自增,因为你不知道哪个master是最近一次做自增操作的。所以我们有另外一个服务器,由它来专门提供这些自增数字。这个服务器也有两个。其中一个只产生奇数,而另一个只产生偶数。 这就是用户ID帐户的来源。

几个月前,这个服务器的数字超过了231,所以溢出了32位的整数列,但这也不是太大的问题,因为你可以把它保存在一个64位的列中。然而,在代码中的一些地方并没有这么做。但是,大家并没有意识到为什么ID突然出现了64位。因此,当ID太大时,一些相关的特性就无法工作了。

这些地方的代码无法得到合理的ID,但仍旧试图把它保存到数据库上,但数据库无法保存它。当这个问题发生时,我们立刻要求大家不要再推送代码了。我们只花了大约一分钟就找到了这个故障的原因,因为在日志里有很多错误信息,这些信息中能看到那些数字。如果之前你看到过这样的数字,你会就发现这个问题。你能想像得到当看到这样的数字时,那种不祥的感觉。

我们看到后,我们就立刻停止推送,是我们的团队(core platform team)发现它的。尽管我们知道这是一个严重的问题,但我们并不知道有多少数据库表使用了它,因为没有地方可以看到这样的信息。我们召集大家,包括一些运维工程师和我们团队的一些人,到会议里来讨论如何处理这个问题。最后决定相看所有的表,看看到底哪些数据库表的列宽不足。

在数据库里,代码中,以及写的schemas中都可能有相关的信息。所以我们只能查看所有的代码,来判断有多少schemas中存在这个问题。有些只是代码中有问题,有些只是在数据库中有问题。有些地方则是两方面都有问题。同时,其他人来判断哪些特性受到了牵连。我们从错误日志中有可能发现这些受牵连的特性,也可能从图表上发现。只要发现了,就可以找以相应的配置文件,把这些特性关掉。

一旦我们修改好所有的地方,我们就可以在数据库上运行这些变更,将那些字段改成64位,再把关掉的特性开关打开,然后马上监控,看哪些数据还会出异常。整个过程只持续了几个小时,而且只有几个比较小的特性受到了影响。但直到把全部问题都修复了,我们才能知道到底有多少特性受到了影响。因为很多影响不是显而易见的。

InfoQ:这是一个相当快的修复了。

Sam:是的,这是最糟糕的故障之一。我想,在过去的几年里我们并没有出现太多的问题。在过去的几年只,可能停机的时间不超过三小时,停机事件也很少发生。如果真发生了,那绝对是很糟糕的事情。

监控

InfoQ:你们如何做服务器监控?我是指网络性能监控和应用程序的监控。

Sam:对于网络性能,我们用Cacti,以及我们自己写的一个工具,叫做FITB,在Github上开源了。他会监控所有的switch,并保持那些度量项数据比较少。它有点儿像Cacti。但我不记得到底区别在哪里了,因为我很少处理网络度量数据。我们用这两个工具监控不同端口上switch的性能。我们在这方面很少遇到问题。网络几乎没有给我们带来任何麻烦。我们的容量目前是足够的。

InfoQ:那么,系统常见的瓶颈在哪里呢?

Sam:更多的是数据库和memcache。最近,我们在memcache上遇到了问题,而且与网络相关。有很多特别关键的数据保存在memcache中,很多人都需要用。最近,在美国,我们的流量陡增。好象是在Cyber Monday(译者注:感恩节假期之后的第一个上班日的网购促销活动),流量非常高,有一个关键数据被访问了很多次,其中的一个memcache服务器占满了网络连接。而对这个问题的修复方法只是不再把这个数据放在memcache中了。因为根本不需要放在那里,所以我们就把它从那里删除了。但这个修复并不合理,因为直到网卡饱和了,我们才发现。

我们用Cacti,但我并不知道它的监控频度是多少,也不知道其他人隔多长时间来看一下数据。当然,我们用Nagios来监控这个数据,判断事情是否出了问题。

对于客户端数据,我们有自己的一套信号器,记录用户在网站上的操作,这些信息会保存到我们的大数据栈上。对于用户行为的监控,我们使用Hadoop集群,来处理分析这些信号量,比如我加载了主页,点击了一个物品,并买下了它。我们会观察分析这类的操作模式。我们也会将前端JavaScript的错误记录到后台。我们既有服务器端的性能测试,也有web页面的测试,并经常运行它们。我们有一个web页面测试集群,用它来判断性能是否达到许可水平。

我们也会将应用程序的度量数据与用户的行为做关联。所以我们会度量有多少人在网站上查询买品列表,以便来衡量用户是如何使用我们的网站的。如果这样的操作不再发生了,那么也许我们应该在用户体验方面要改点儿什么东西了。我们也会保存我们帮助论坛的那些图片。这样的话,如果越来越多的人在帮助论坛中请求帮助的话,那么很可能我们破坏了什么功能。当然,还有来自客服的信息,我们常常和他们沟通来尝试判断用户遇到的问题。

查看英文原文Interview: Sam Haskins from Etsy on Code Deployment, Monitoring and Failure Procedures


感谢 黄冬对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至 [email protected]。也欢迎大家通过新浪微博( @InfoQ)或者腾讯微博( @InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

您可能也会喜欢

相关 [文章 etsy 工程师] 推荐:

文章: Etsy工程师Sam Haskins谈代码部署,监控与故障处理

- - InfoQ cn
在本次访谈中,Sam Haskins分享了他在Etsy做DevOps的经验. Etsy使用Git做代码管理,平均每天提交的更新数量在30次左右,有时甚至达到70个. 在如此高频率提交代码的情况下,他们如何进行代码审查. 如何在每次更新之后监控系统性能. ScrumMaster鲍央舟:Scrum权威培训及工程实践.

文章: 我为什么向后端工程师推荐Node.js

- Johnny - InfoQ cn
科普文一则,说说我对Node.js的一些认识,以及我作为前端工程师为什么会向后端工程师推荐Node.js. Hadoop、HBase、MongoDB和Cassandra等技术在当前的企业中的应用. Sybase在线研讨会:云时代的列式数据库——Sybase IQ15.3新特性(8月22日 周一). 百度技术沙龙第十七期:富客户端时代的JavaScript框架(8月20日 周六).

Boticca 把 Etsy 模式带到高端全球设计领域

- Kofai - 36氪
今年年初,爱沙尼亚珠宝设计师 Krista Raak 在巴黎的一个小型艺术品市场出售手工刺绣项链,后来她的作品被 Boticca.com 创始人发现,然后受邀加入该公司的全球首饰市场,Raak 一直想把自己的作品走出街旁集市和精品店,于是欣然接受. 合作三个月之后,Raak 已经获得大约1万美元的销售额,她拿80%.

手作商品哪裡買?來去逛逛Etsy、Pinkoi及wowsai網

- Amo - Inside 網路趨勢觀察
拍賣逛膩了,千篇一律的主流商品再也看不上眼,想送點不一樣的禮物給朋友,或想佩帶不一樣的飾品,這個時候可以來看看流行了一段時間的Etsy(美國)、Pinkoi(台灣)及Wowsai(中國)購物網站,這些網站雖然來自不同地方,但都有一個共同點-它們都是一個販賣手工製作或設計商品的購物網站. LBS地點簽到的下一步:商品簽到、同好簽到.

什么样的硬件配置在驱动 Etsy

- - 博客 - 伯乐在线
前言:Etsy.com 是家手工艺品拍卖网站,据其 CEO 查德·迪克森(Chad Dickerson)日前透露,该公司今年截至目前处理的交易总额已经突破了5亿美元. 他们目前拥有超过300名员工,80万活跃商户以及超过4000万月访问用户. 那这样一个大网站,其硬件配置如何. Etsy 官方技术博客有文章介绍, @忘美流星 编译如下.

遭遇工程师

- Chrisoul - 槽边往事
谢谢大家的关心,几个小时前Google Plus恢复了我的帐号,看来暂时我还不用离开. 因为前一篇Blog的缘故,有些网友猜测是因为博文而使得我获释. 虚荣心让我想立即承认这一点,但是对不起,真的不是这样的,我的Blog并没有那么大影响力,尤其是在英文世界里. 而且,因为我上次张贴了一张人类进化谱系的漫画,我在国外驻京记者圈里成功赢得了“种族主义者”这一臭名昭著的称号,大概没有什么人愿意帮助一个黄种人中的“种族主义者”.

工程师效率

- - 后端技术 by Tim Yang
很好奇程序员这个群体这些年效率是变低了还高了,在社交媒体中,各个阶层的兴趣圈都有自己的段子手及内容帐号,段子手发的内容会让你笑cry,内容帐号发的内容可让你享受阅读的快感,这些快感会比写代码见效快. 写完一个模块的代码通常要一整天或者几天时间,代码调通运行没有问题才会体验到愉悦,而社交媒体只需要一些碎片时间就可以达到高潮.

知乎招募工程师

- oxygen - 知乎的博客
Python工程师  有两年以上软件开发经验. 至少一年 Python 开发经验. 对开源技术有强烈的兴趣和爱好,参与或向开发者提交过bug和patch. 热爱探索和钻研,熟悉文本挖掘、自然语言处理相关知识能使用C/C++独立实现复杂的算法结构熟悉开源搜索项目(Lucene,Sphinx等)极强的逻辑分析能力对开源技术有强烈的兴趣和爱好,参与或向开发者提交过bug和patch认为自己是技术geek有极强的责任感.

浅谈技术工程师的进步

- belltoy - caoz的和谐blog
本来发微博的,越说越多,算了,发篇博客把,说点工程师如何取得进步的问题,. 1:描述和记录问题要精确,数字化,“负载很高,连接很多,速度很卡”这种描述都是不对的,负载uptime值多少,连接数具体有多少,平时正常多少,高峰多少,访问延迟有多大,全部要数字化,而且要有问题状况下和平时的对比,养成这样的习惯,技术分析能力才会有进步.

工程师与会计 [幽默笑话]

- Liqun - 经典网文_来福岛爆笑娱乐网
  有三个工程师和三个会计一起去外地开会,上火车时三个会计买了三张车票,而三个工程师却只买了一张票,会计很不解,工程师说:“上了车你们就知道了”.   火车刚一开动三个工程师就挤进了一个厕所,列车员开始检票最后走到了厕所外边,她敲了一下门说:“检票”. 然后门开了一个小缝,从里面递出一张车票.   在外地开完会后在返回的时候会计们觉得工程师们的方法很不错于是也只买了一张车票,而这次工程师一张票也没有买,会计们又很不解,工程师还是说:“上了车你们就明白了”.