Lisy's blog Lisy's blog
首页
后端
前端
读书
关于

新晴

做事情积极主动。积极主动不仅指行事的态度,还意味着为人一定要对自己的人生负责。个人行为取决于自身的抉择,而不是外在的环境,人类应该有营造有利的外在环境的积极性和责任感。
首页
后端
前端
读书
关于
  • Java

  • linux

  • python

  • 其他

    • 为知笔记记录了我的职业生涯
    • Instagram 如何仅用 3 名工程师扩展到 1400 万用户
      • 译文
    • obsidian同步方案(termux+git)
  • python

  • 后端
  • 其他
lisy
2023-11-04
目录

Instagram 如何仅用 3 名工程师扩展到 1400 万用户

原文链接:How Instagram scaled to 14 million users with only 3 engineers (substack.com) (opens new window)

# 译文

(其他说明:使用edge浏览器的自带的翻译功能,居然把题目的意思都翻译错了。所以使用浏览器插件SingleFile保存为html文件,然后上传文件到poe的claude2-100k中,让它做的翻译,内容相对准确)

Instagram 在 2010 年 10 月到 2011 年 12 月的一年多时间里,用户数从 0 扩展到了 1400万。而这仅仅依靠 3 名工程师完成。

他们遵循了 3 个关键原则,并采用了可靠的技术栈。

Instagram 的指导原则:

保持极简。
不要重造轮子。
尽可能使用成熟可靠的技术。

技术栈简单解释:

早期 Instagram 的基础设施运行在 AWS 上,使用 EC2 的 Ubuntu Linux。 EC2 是亚马逊提供的可租用虚拟计算机的服务。

为了简单起见,我们从用户角度来看一个用户会话的流程。(标记为 Session)

前端
Session: 用户打开 Instagram 应用。

Instagram 最初在 2010 年作为 iOS 应用推出。由于 Swift 在 2014 年才发布,我们可以假设 Instagram 是使用 Objective-C 和一些其他技术如 UIKit 开发的。

负载均衡
Session: 在打开应用后,一个获取主 Feed 照片的请求被发往后端,先被 Instagram 的负载均衡器接收。

Instagram 使用的是亚马逊的 Elastic Load Balancer。他们有 3 个 NGINX 实例,根据健康状况被轮流使用。

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

后端
Session: 负载均衡器将请求发往应用服务器,应用服务器负责正确处理请求的逻辑。

Instagram 的应用服务器使用 Django 和 Python 开发,使用 Gunicorn 作为 WSGI 服务器。WSGI(Web Server Gateway Interface)用来将请求从 web 服务器转发到 web 应用。

Instagram 使用 Fabric 在许多实例上并行执行命令。这使得代码可以在几秒钟内被部署。

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

数据存储
Session: 应用服务器发现请求需要主 Feed 的数据。例如需要:

最新的相关照片 ID
匹配这些照片 ID 的实际照片
这些照片的用户数据

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

应用服务器会从 PostgreSQL 获取数据,PostgreSQL 存储了 Instagram 大部分的数据,比如用户和照片元数据。

Postgres 和 Django 之间的连接通过 Pgbouncer 池化。

由于接收数据量巨大(每秒超过 25 张照片和 90 个赞),Instagram 对数据进行了分片。他们使用代码将几千个逻辑分片映射到少数物理分片。

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

41 bit 表示时间戳(毫秒),可以支持 41 年的 ID (自定义时期)
13 bit 表示逻辑分片 ID
10 bit 表示一个自动增长的序列,模数 1024。这意味着我们可以每毫秒内每个分片生成 1024 个 ID

(可以在这里阅读更多)

得益于 Postgres 中可按时间排序的 ID,应用服务器成功获取到了最新的相关照片 ID。

照片存储:S3 和 Cloudfront
Session: 应用服务器使用快速的 CDN 链接获取匹配这些照片 ID 的实际照片,使其可以快速加载。

数 TB 的照片存储在亚马逊 S3 中。这些照片通过亚马逊 CloudFront 快速提供给用户。

缓存:Redis 和 Memcached
Session: 为了从 Postgres 获取用户数据,应用服务器(Django)使用 Redis 中的映射匹配照片 ID 和用户 ID。

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

通过一些巧妙的散列,Instagram 能够在不到 5GB 的空间里存储 3 亿条键值映射。

这个照片 ID 到用户 ID 的键值映射对于知道需要查询哪个 Postgres 分片是必需的。

Session: 通过使用 Memcached 高效的缓存,从 Postgres 获取用户数据很快,因为响应已经被缓存。

对于通用缓存,Instagram 使用了 Memcached。他们当时有 6 个 Memcached 实例。在 Django 上加 Memcached 相对简单。

有趣的事实:在 2013 年,也就是 2 年后,Facebook 发表了一篇论文,讲述了他们如何扩展 Memcached 从而帮助他们处理每秒数十亿次请求。

Session: 用户现在看到主界面上显示自己关注的人发布的最新的图片。

主从复制
Postgres 和 Redis 都以主从方式运行,并使用亚马逊 EBS (Elastic Block Store) 快照频繁备份系统。

推送通知和异步任务
Session: 现在,假设用户关闭了应用,但随后收到一个好友发布照片的推送通知。

这个推送通知通过 pyapns 发送,和 Instagram 已经发送出的数十亿推送通知一样。pyapns 是一个开源的通用苹果推送服务提供商。

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

后端将这个任务推入 Gearman,一个任务队列,将工作分发给更适合的机器。Instagram 有大约 200 个 Python 工作进程消费 Gearman 任务队列。

Gearman 用于多个异步任务,比如向一个用户所有的关注者推送活动(像是新照片发布),这称为 fanout。

监控
Session: 呀,Instagram 应用崩溃了,因为服务器端出了错误导致发送了错误的响应。3 名 Instagram 工程师立即收到警报。

Instagram 使用开源的 Django 应用 Sentry 来实时监控 Python 错误。

Munin 用于图形化系统指标并在异常时报警。 Instagram 有大量定制的 Munin 插件来跟踪应用级指标,比如每秒发布照片数量。

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

最终架构概览

非常感谢您的阅读!就像早期的 Instagram,我也尽量保持简单。

上次更新: 2024/01/07, 07:44:52
为知笔记记录了我的职业生涯
obsidian同步方案(termux+git)

← 为知笔记记录了我的职业生涯 obsidian同步方案(termux+git)→

最近更新
01
Anaconda conda命令速查
01-05
02
奇特的一生
06-16
03
docker学习
02-16
更多文章>
Theme by Vdoing | Copyright © 2020-2025 lisy | 备案号:鲁ICP备18023702号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式