从 0 到 1400 万用户,3 名工程师如何撑起 Instagram?

文章详细描述了Instagram在短时间内迅速增长的背后,如何通过保持简单、利用成熟技术、负载均衡和分布式架构,如AWS、Postgres、Django、Redis等,实现高效服务和扩展。同时提及了监控和通知系统的运用。

482a7ff686bf45a252503eecde3a0624.gif

Instagram,是 Meta 于 2010 年推出的一款免费提供在线图片及视频分享的社群应用软件。在推出短短一年的时间里,Instagram 迅速“蹿红”,它的用户数量从 0 增长到了 1400 万。而在这背后,只有三名工程师在支撑。

Instagram 的成功,成为很多软件产品学习的楷模,那么它究竟是怎么做到的?背后运用了哪些技术栈?近日,一篇文章初探了其中的秘密。

来源:https://engineercodex.substack.com/p/how-instagram-scaled-to-14-million

翻译工具 | ChatGPT   责编 | 苏宓

出品 | 优快云(ID:优快云news)

以下为译文:

从 2010 年 10 月到 2011 年 12 月,Instagram 在短短一年多的时间里,用户数量从 0 增长到了 1400 万。他们仅仅依靠 3 名工程师实现了这一壮举。

他们之所以能够做到这一点,是因为遵循了 3 个关键原则并采用了可靠的技术堆栈。

Instagram 的指导原则:

1. 保持极度简单。

2. 不要重新发明轮子。

3. 在可能的情况下使用经过验证的、稳定的技术。

2adb319e902073dd78d5e584c2acf299.png

Instagram 背后的技术堆栈

早期的 Instagram 基础设施在 AWS 上运行,使用了带有 Ubuntu Linux 的 EC2。EC2 是亚马逊的一项服务,允许开发人员租用虚拟计算机。

为了简化说明,这里从工程师的角度来看用户会话的生命周期(下文标注为“Session:”),从而捋清楚 Instagram 所用到的一些技术。

前端

Session:用户打开 Instagram 应用。

Instagram 最初于 2010 年作为 iOS 应用推出。由于 Swift 于 2014 年发布,我们可以猜测 Instagram 是使用 Objective-C 以及其他如 UIKit 的组合技术来编写的。

adaafe7622b12be5c247f88f9f3fafdb.png

负载均衡

Session:打开应用后,向后端发送请求以获取主要的动态照片,该请求将被发送到 Instagram 的负载均衡器。

Instagram 使用了亚马逊的弹性负载均衡器。工程师租用了 3 个 NGINX 实例,并根据它们的健康状态进行交替切换。

每个请求首先会被发送到负载均衡器,然后再路由到实际的应用服务器。

db825d8f2ca7c589dd6a3cf775f46500.png

后端

Session:负载均衡器将请求发送到应用服务器,应用服务器负责保存处理请求的逻辑。

Instagram 的应用服务器使用 Django 框架以及它是用 Python 编程语言编写的,并选择 Gunicorn 作为他们的 WSGI 服务器。

值得一提的是,WSGI(Web 服务器网关接口)将请求从 Web 服务器转发到 Web 应用程序。

Instagram 使用 Fabric 在多个实例上并行运行命令。这允许他们在几秒内部署代码。

这些应用服务器运行在超过 25 台亚马逊高性能 CPU 大型服务器上。由于服务器本身是无状态的,当需要处理更多请求时,他们可以添加更多服务器。

c585e062caa4ea81accce46b1b76ae87.png

通用数据存储

Session:应用服务器意识到请求需要主要动态数据。为此,让我们假设它需要:

  • 最新相关的照片 ID

  • 与这些照片 ID 匹配的实际照片

  • 这些照片的用户数据。

数据库:Postgres

Session:应用服务器从 Postgres 中获取最新相关的照片 ID。

应用服务器会从存储了大部分 Instagram 数据的 PostgreSQL 中提取数据,包括用户和照片元数据。

Postgres 和 Django 之间的连接使用 Pgbouncer 进行连接池化管理。

由于 Instagram 收到的数据量很大(每秒超过 25 张照片和 90 个点赞),工程师对数据进行了分片。他们使用代码将数千个“逻辑”分片映射到少数物理分片上。

Instagram 面临并解决的一个有趣挑战是生成可以按时间排序的 ID。他们生成的可按时间排序的 ID 如下:

  • 用 41 位表示毫秒级时间(使用自定义时期,可提供 41 年的 ID)

  • 用 13 位表示逻辑分片 ID

  • 用 10 位表示自动递增序列,模数为 1024。这意味着我们可以在每个分片中每毫秒生成 1024 个 ID

由于在 Postgres 中使用可按时间排序的 ID,应用服务器已成功接收到最新相关的照片 ID。

照片存储:S3 和 Cloudfront

Session:应用服务器获取与这些照片 ID 匹配的实际照片,并使用快速 CDN 链接,以便为用户快速加载这些照片。

数千字节的照片存储在 Amazon S3 中。这些照片通过 Amazon CloudFront 迅速提供给用户。

缓存:Redis 和 Memcached

Session:为了从 Postgres 中获取用户数据,应用服务器(Django)使用 Redis 将照片 ID 与用户 ID 匹配。

Instagram 使用 Redis 存储了大约 3 亿张照片与创建它们的用户 ID 的映射,以便在获取主要动态数据、活动动态数据等时知道要查询哪个分片。所有的 Redis 都存储在内存中,以降低延迟,并分布在多台机器上。

通过一些巧妙的哈希处理,Instagram 成功地将 3 亿个键映射存储在不到 5GB 的空间中。

为了知道要查询哪个 Postgres 分片,需要这种 photoID 到 user ID 的键-值映射。

Session:由于最近已经缓存响应,通过高效的 Memcached 缓存获取用户数据,从 Postgres 获取数据的速度很快。

对于一般的缓存,Instagram 使用了 Memcached。那时他们有 6 个 Memcached 实例。在 Django 上使用 Memcached 相对简单。

有趣的事实:2 年后,即在 2013 年,Facebook 发布了一篇关于如何扩展 Memcached 以帮助他们处理每秒数十亿请求的重要论文。

Session:用户现在可以看到主页动态,其中包含他正在关注的人的最新照片。

06664b175f675d8cbb4cbe763cae0237.png

主从设置

Postgres 和 Redis 都在主从设置下运行,并使用 Amazon EBS(弹性块存储)的快照功能来频繁备份系统。

b0b4f7b78a2012c65b51b5d43278a699.png

推送通知和异步任务

Session:现在,假设用户关闭了应用,但后来收到了一个朋友发布了一张照片的推送通知。

这个推送通知是使用 pyapns 发送的,以及 Instagram 发送出的十亿多条其他推送通知。Pyapns 是一个开源的通用苹果推送通知服务(APNS)提供商。

Session:用户非常喜欢这张照片!所以他决定在 Twitter 上分享它。

在后端,这个任务被推送到 Gearman,这是一个任务队列,用于分配适合的机器来处理工作。Instagram 拥有大约 200 个 Python 工作程序来消耗 Gearman 任务队列。

Gearman 被用于多个异步任务,比如向所有用户的粉丝(称为粉丝传播)推送活动信息(比如发布新照片)。

cf565602443a9961cd2a7d80a424a722.png

1f08705c795c25e2820ae7fa7047f497.png

监控

Session:糟糕!Instagram 应用程序崩溃了,因为服务器上出现了错误,并发送了错误的响应。三名 Instagram 工程师立即收到警报。

Instagram 使用 Sentry,一个开源的 Django 应用程序,实时监控 Python 错误。

Munin 用于绘制系统范围的指标和警告异常。Instagram 有很多自定义的 Munin 插件来跟踪应用级别的指标,比如每秒发布的照片数量。

Pingdom 用于外部服务监控,PagerDuty 用于处理事故和通知。

e1537f9c2403b26da966aa99c05e741c.png

最终架构概述

888e07399f1e06924eeea3c3cc3d59a3.png

推荐阅读:

AI女友突然断崖式分手,独留对象在贴吧发心碎小作文!

下一轮角逐即将开启,"移动云杯"晋级赛道决赛名单公布

深圳一公司奖励程序员38g黄金空格键,价值近2万元,网友:“每次敲击一下都是钱声!”

基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)内容概要:本文档围绕基于遗传算法的异构分布式系统任务调度算法展开研究,重点介绍了一种结合遗传算法的新颖优化方法,并通过Matlab代码实现验证其在复杂调度问题中的有效性。文中还涵盖了多种智能优化算法在生产调度、经济调度、车间调度、无人机路径规划、微电网优化等领域的应用案例,展示了从理论建模到仿真实现的完整流程。此外,文档系统梳理了智能优化、机器学习、路径规划、电力系统管理等多个科研方向的技术体系与实际应用场景,强调“借力”工具与创新思维在科研中的重要性。; 适合人群:具备一定Matlab编程基础,从事智能优化、自动化、电力系统、控制工程等相关领域研究的研究生及科研人员,尤其适合正在开展调度优化、路径规划或算法改进类课题的研究者; 使用场景及目标:①学习遗传算法及其他智能优化算法(如粒子群、蜣螂优化、NSGA等)在任务调度中的设计与实现;②掌握Matlab/Simulink在科研仿真中的综合应用;③获取多领域(如微电网、无人机、车间调度)的算法复现与创新思路; 阅读建议:建议按目录顺序系统浏览,重点关注算法原理与代码实现的对应关系,结合提供的网盘资源下载完整代码进行调试与复现,同时注重从已有案例中提炼可迁移的科研方法与创新路径。
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文提出了一种基于非支配排序的蜣螂优化算法(NSDBO),用于求解微电网多目标优化调度问题。该方法结合非支配排序机制,提升了传统蜣螂优化算法在处理多目标问题时的收敛性和分布性,有效解决了微电网调度中经济成本、碳排放、能源利用率等多个相互冲突目标的优化难题。研究构建了包含风、光、储能等多种分布式能源的微电网模型,并通过Matlab代码实现算法仿真,验证了NSDBO在寻找帕累托最优解集方面的优越性能,相较于其他多目标优化算法表现出更强的搜索能力和稳定性。; 适合人群:具备一定电力系统或优化算法基础,从事新能源、微电网、智能优化等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统的多目标优化调度设计;②作为新型智能优化算法的研究与改进基础,用于解决复杂的多目标工程优化问题;③帮助理解非支配排序机制在进化算法中的集成方法及其在实际系统中的仿真实现。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注非支配排序、拥挤度计算和蜣螂行为模拟的结合方式,并可通过替换目标函数或系统参数进行扩展实验,以掌握算法的适应性与调参技巧。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值