Instagram的技术架构

标签: 程序设计 架构 | 发表时间:2012-06-18 18:41 | 作者:标点符
出处:http://www.biaodianfu.com

Instagram 被 Facebook 以10亿美金收购。团队规模:13 人。而在被Facebook收购前的一个月,整个团队才7名员工。

  • 2010年: 2位工程师
  • 2011年: 3 位工程师
  • 2012年: 5 位工程师

制胜法宝:

  1. 广泛的单元测试和功能测试
  2. 坚持 DRY(Don’t Repeat Yourself)原则
  3. 使用通知/信号机制实现解耦
  4. 我们大部分工作使用Python来完成,只有逼不得已的时候,才会用C
  5. 频繁的代码复查,尽量保持“智慧共享”。(frequent code reviews, pull requests to keep things in the ‘shared brain’)
  6. 广泛的系统监控

Instagram的两个创始人

  • Mike Kriegerr:之前是一个颇为低调的工程师和用户体验设计师,他在一家名叫Meebo的创业公司工作了1年半。analytics & python @ meebo(在Meebo做分析,使用python );
  • Kevin Systrom:毕业后在Google的收购部门工作了一年,今年28岁,随后去到了一家从事旅行业务的创业公司Nextstop,没有计算机学位,没有接受过正式培训, 但他下班后坚持自学编程,在这家创业公司被Facebook以人才收购的方式收购后,Systrom又去早期的Twitter实习了一段时间。

下面一起来看下这个奇迹是怎样搭建的?Instagram的技术实现是什么?以下内容来自翻译。

当我们与其他工程师偶遇和交流的时候,有一个问题经常被问及,“你们的技术架构(technology stack)是怎么样的”?我们觉得从较高的层次来描述Instagram的所有构成系统是一件有趣的事情;未来你可能期待更深入的描述这些系统。这就是我们的系统,仅仅1年时间,并且我们活了下来,其中有一部分我们一直在修改。一个小型团队的初创公司,可以在一年多一点时间发展到1400多万用户规模。

Instagram 开发团队奉行的三个核心原则:

  • Keep it very simple (极简主义)
  • Don’t re-invent the wheel (不重复发明轮子)
  • Go with proven and solid technologies when you can(能用就用靠谱的技术)

操作系统 / 主机

我们在Amazon EC2上跑Ubuntu Linux 11.04 (“Natty Narwhal”),这个版本经过验证在 EC2 上够稳定。我们发现之前的版本在EC2上高流量的时候都会出现各种不可预测的问题( freezing episodes)。因为只有3名工程师,我们的需求依然在不断的变化中,因此自托管主机不是我们的选择,也许未来当用户量空前增长的时候,我们会考虑。

负载均衡
每一个对Instagram 服务器的访问都会通过负载均衡服务器;我们使用2台 nginx机器做DNS轮询。这种方案的缺点是当其中一台退役时,需要花时间更新DNS。最近,我们转而使用Amazon的ELB(Elastic Load Balancer)负载均衡器,使用3个NGINX 实例可以实现调入调出(and are automatically taken out of rotation if they fail a health check);我们同时在 ELB 层停掉了 SSL , 以缓解nginx的 CPU 压力。我们使用Amazon的Route53服务作为DNS服务,他们最近在AWS控制台上增加了一套很好的GUI工具。

应用服务器

接下来是应用服务器用来处理我们的请求。我们在Amazon的High-CPU Extra-Large机器上运行了 Django ,随着用户的增长,我们已经在上面跑了25个 Django实例了(幸运地,因为是无状态的,所以非常便于水平扩展)。我们发现我们的个别工作负载是属于计算密集型而非IO密集型,因此High-CPU Extra-Large类型的实例刚好提供了合适的比重(CPU和内存)。

使用 Gunicorn 作为 WSGI 服务器。过去曾用过 Apache 下的 mod_wsgi 模块,不过发现 Gunicorn 更容易配置并且节省 CPU 资源。使用 Fabric 加速部署。 Fabric最近增加了并行模式,因此部署只需要花费几秒钟。

数据存储

我们大部分数据(用户信息,照片的元数据、标签等)存储在PostgreSQL中;我们 之前已经说了关于如何基于不同的Postgres 实例进行切分的。我们的主要分片集群包含12个四倍超大内存云主机(且12个副本在不同的区域);

我们发现亚马逊的网络磁盘系统(EBS)每秒的寻道能力不够,因此,将我们所有工作放到内存中就变得尤为重要。为了获得合理的性能,创建了软 RAID 以提升 IO 能力,使用的 Mdadm 工具进行 RAID 管理;

顺便提一下,我们发现 vmtouch用来管理内存数据是个极好的工具,尤其是在故障转移时,从一台机器到另一台机器,甚至没有活动的内存概要文件的情况。 这里是脚本,用来解析运行于一台机器上的vmtouch 输出并打印出相应vmtouch命令,在另一台机器上执行,用于匹配他当前的内存状态;

我们所有的PostgreSQL实例都是运行于主-备模式(Master-Replica),基于流复制,并且我们使用EBS快照经常备份我们的系统。为了保证我们的快照的一致性(原始灵感来源于 ec2-consistent-snapshot)我们使用XFS作为我们的文件系统,通过XFS,当进行快照时,我们可以冻结&解冻RAID阵列。为了进行流复制,我们最爱的工具是 repmgr

对于从我们的应用服务器连接到数据,我们很早就使用了 Pgbouncer做连接池,此举对性能有巨大的影响。我们发现 Christophe Pettus的博客 有大量的关于Django、PostgreSQL 和Pgbouncer 秘诀的资源。

照片直接存储在亚马逊的S3,当前已经存储了几T的照片数据。我们使用亚马逊的CloudFront作为我们的CDN,这加快了全世界用户的照片加载时间(像日本,我们第二最受欢迎的国家)

我们也广泛的使用了 Redis ; 我们的main feed、activity feed、sessions系统( 这里是我们的Django session backend),和其他 相关系统 都使用了 Redis。因为所有的Redis数据都需要放在内存中,因此我们最后使用了几个四倍超大内存云主机用于跑Redis。我们的Redis也是运行于主-备模式(Master-Replica),并且经常将DB保存到磁盘,最后使用EBS快照备份这些数据(我们发现在主机上进行导出太费劲了)。由于Redis 允许写入备份,使得在线故障转移非常方便,转移到一台新的Redis 机器,而不需要停机。

为了我们的 geo-search API,我们一直使用PostgreSQL了很多个月,不过后来迁移到了 Apache Solr.他有一套简单的JSON接口,这样我们的应用程序相关的,只是另一套API而已。

最后,和任何现代Web服务一样,我们使用了Memcached 做缓存,并且当前已经使用了6个Memcached 实例,我们使用pylibmc & libmemcached进行连接。Amzon最近启用了一个灵活的缓存服务(Elastic Cache service),但是它并不比运行我们自己的实例便宜,因此我们并没有切换上去;

任务队列&推送通知

当一个用户决定分享一张Instagram 的照片到Twitter 或Facebook,或者是当我们需要通知一个 实时订阅者有一张新的照片贴出,我们将这个任务推到 Gearman,一个任务队列系统能够写于Danga。这样做的任务队列异步通过意味着媒体上传可以尽快完成,而“重担”可以在后台运行。我们大概有200个工作实例(都用Python写的)在给定的时间内对队列中的任务进行消费,并分发给不同的服务。我们的feed feed fan-out也使用了Gearman,这样posting就会响应新用户,因为他有很多followers。

对于消息推送,我们找到的最划算的方案是 https://github.com/samuraisam/pyapns,一个开源的Twisted 服务,已经为我们处理了超过10亿条通知,并且绝对可靠。

监控

对于100多个实例,监控变得非常重要。我们使用 Munin进行图形化度量。我们基于 Python-Munin,也写了很多Munin 插件。用于图形化度量非系统级的东西(例如,每秒的签入人数,每条照片发布数等)我们使用 Pingdom作为外部监控服务, PagerDuty 用于事件通知。

Python错误报告,我们使用 Sentry,一个Disqus的工程师写的令人敬畏的开源的Django app。在任何时间,我们可以开始工作,并实时的查看我们的系统发生了什么错误。

以上内容翻译自: http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances-dozens-of

Instagram的技术变迁

创业初期:

  1. 初存储采用CouchDB(Apache CouchDB 是一个面向文档的数据库管理系统)
  2. 最初只有一台服务器(在洛杉矶),比一台比MacBook Pro强不到哪里去。

技术更新

一、数据库扩展

早期使用django ORM+postgresql,因为PostGIS,选择了postgresql。(PostGIS在对象关系型数据库PostgreSQL上增加了存储管理空间数据的能力,相当于Oracle的spatial部分)并且数据库部署在独立服务器上。

因为EC2机器的最大内存为68G,随着照片存储量的增加,进行垂直分区(vertical partitioning);使用django db routers,做垂直分区变得很容易;如下:照片则映射到photodb

def db_for_read(self, model):
    if app_label == 'photos':
        return 'photodb'

当照片存储量大于60G的时候,采用水平分区(也就是所谓的“分片”sharding)

sharding带来的问题:

1、数据的检索,hard to know what your primary access patterns will be w/out any usage in most cases, user ID

2、当有分片变得太大的时候怎么办?

基于范围的分片策略(就像MongoDB那样)

3、性能有下降趋势,尤其在EC2上,原因:disk IO,解决方法:预先切分(pre-split),即预先切分上千个逻辑切片,将它们映射到较少的物理分区节点中去。

关于相关内容,更详细的可以参看 这里

二、 选择合适工具

进行缓存/反规范化数据设计

用户上传图片时:

  1. 用户上传带有标题信息和地理位置信息(可选)的照片;
  2. 同步写到这个用户对应的数据库(分片)中;
  3. 进行队列化处理
  • a、如果带有地理位置信息,通过异步的POST请求,将这个图片的信息送到Solr(Instagram 用于 geo-search API的全文检索服务器)。
  • b、跟随者的信息分发(follower delivery),即告诉我的follower ,我发布了新的照片。如何来实现的呢?每个用户都有一个follower 列表,新照片上传时会把照片ID发送给列表中的每一个用户,用Redis 来处理这一业务简直太棒了,快速插入,快速子集化(rapid subsets,什么意思?是指获取部分数据吗?
  • c、when time to render a feed,we take small # of IDs, go look up info in memcached(当需要生成feed的时候,我们通过ID+#的格式,直接在memcached中查找信息)

Redis适合什么样的场景?

  1. 数据结构相对有限;
  2. 对频繁GET的地方,对复杂对象进行缓存;

不要将自己绑定在非得以内存数据库为主要存储策略的方案上(don’t tie yourself to a solution where your in-memory DB is your main data store

参考链接: http://www.cnblogs.com/xiekeli/archive/2012/05/28/2520770.html

Related posts:

  1. Google索引库到底有多大的猜想
  2. 使用Python来连接MySQL
  3. 百度索引库有多大

相关 [instagram 技术 架构] 推荐:

Instagram的技术架构

- - 标点符
Instagram 被 Facebook 以10亿美金收购. 而在被Facebook收购前的一个月,整个团队才7名员工. 2011年: 3 位工程师. 2012年: 5 位工程师. 坚持 DRY(Don’t Repeat Yourself)原则. 使用通知/信号机制实现解耦. 我们大部分工作使用Python来完成,只有逼不得已的时候,才会用C.

Instagram: 2年10亿美元背后的技术架构

- - 开放博客
参考: Instagram的技术探索. Instagram是一款免费照片分享移动应用,目前支持IOS和Android. 在1年多的时间里,Instagram发展到140万个用户,1.5亿张图片(几个TB),仅有3个工程师,以10亿美元的天价被Facebook收购. 不得不说,Instagram是业界的一个神话.

Instagram 架构分析笔记

- Yousri - DBA Notes
Instagram 团队上个月才迎来第 7 名员工,是的,7个人的团队. 作为 iPhone 上最火爆的图片类工具,instagram 用户数量已经超过 1400 万,图片数量超过 1.5 亿张. 不得不说,这真他妈是个业界奇迹. 几天前,只有三个人的 Instagram 工程师团队发布了一篇文章:What Powers Instagram: Hundreds of Instances, Dozens of Technologies,披露了 Instagram 架构的一些信息,足够勾起大多数人的好奇心.

了解Instagram背后的技术

- - InfoQ cn
刚被Facebook以10亿美金收购的著名手机照片分享应用 Instagram最近吸引了无数人的眼球, Android版本登陆Google Play不到一个月下载量就突破1000万,总用户数即将超过5000万. Instagram联合创始人Mike Krieger说 他们用了8周时间打造了最初的Instagram,但现在的系统肯定已经今非昔比.

Instagram的变异

- 小白 - 互联网的那点事...
周末打算写手机拍照社交,为查资料,仔细看了看Instagram(最近两个月我的活跃度明显降低),大吃一惊,和年初我还活跃那阵子相比变化极大,之前的论点几乎全被推翻. 我之前的论点是这样的:手机拍照社交产品存在两个天然瓶颈. 第一个瓶颈是“信息”,即通过手机拍照传递出去的信息. 在传统渠道里,常见情形是摸出手机给朋友看,边看边讲,这是我家猫猫狗狗的相片,这是我去xxx玩的时候拍的相片——信息通过面对面的交流来传递.

Instagram的迷思

- Shell Wang - 坏脾气的小肥
这辈子遇到的,令我特别着迷的产品只有两款,2008年5月遇到开心,2010年11月遇到Instagram. 我在Instagram上面已经有200多个follower,哇哈哈哈哈,可惜每天两点一线,又没什么生活情趣,总是发以前去动物园拍的相片. 我猜是“与真实好友分享生活中的这一刻”. 作为背景介绍,Instagram是iPhone上(目前只支持iPhone)新出的APP,据说10天增长了20万个用户.

Instagram启示录

- Wenhuan - 所有文章 - UCD大社区
不管认为Instagram是lomo-twitter还是poladroid+iphoneography. 照片分享服务Instagram于 6个月之前上线,上个月24日公开发布了支持实时功能的API,第三方开发人员可以根据标签、地点和地区抓取照片. 数据显示,Instagram目前每周新增13万用户.

Trover 超越 Instagram ?

- PH囧ENIX - 爱范儿 · Beats of Bits
5月4日,Trover 上线,第二周成为 App Store 的 “本周推荐”,现在已经有来自140个国家的用户上传了照片. Trover 是一家小公司,由3名程序员和一名设计. Trover 的起步和 Instagram 很像,尽管它还有一些不完善的地方,但由于其拥有一些 Instagram 不具备的元素,我认为它将超越 Instagram.

用 Instagram 拍摄 Instagram 办公室

- 笑炊 - 爱范儿 · Beats of Bits
Kevin 分享过 Instagram  的创业故事:四个人,八周时间,推倒重建的项目,吸引了超过 500 万用户,成为 iPhone 平台上最受欢迎的图片分享社区之一. 这家位于旧金山的公司有何过人之处. 记者 Nicholas Jackson 拿着 iPhone 走进了  South Park St.

instagram 和不联网

- sylvia - 爱范儿 · Beats of Bits
by 李楠 (newkhonsou@twitter). instagram 是近期窜红的 iPhone App 和图片分享社区. 仅一周时间就积累了 10 万注册用户. 但 InstaCamera 可不是新玩意,那东西以前叫“拍立得”. 谁拿个 Polaroid 在手,立马文艺的牛比闪闪. 数码时代, Polaroid 没落了.