哈喽大家好,我是咸鱼
想必大家都听说过 Instagram ,它是全球最受欢迎的社交媒体平台之一,拥有数十亿的活跃用户
Instagram 诞生于 2010 年,上线一周就坐拥 10 万注册用户,一年之内就拥有了 1400 万用户,可见扩张趋势突飞猛进。
Instagram 诞生的时候只有 3 个工程师,想必大家对【他们怎么设计后端架构,使用了什么技术来支持这么多用户】很感兴趣吧,那么今天我们就来了解一下 Instagram 是如何在只有 3 名工程师的情况下扩展到 1400 万用户
原文:https://engineercodex.substack.com/p/how-instagram-scaled-to-14-million
从 2010 年 10 月到 2011 年 12 月,Instagram 的用户在一年多的时间里从 0 增加到1400万,关键是他们只有 3 个工程师
这听起来是不是很不可思议。据 Instagram 工程师透露,他们通过遵循下面 3 个关键原则并拥有可靠的技术栈来做到这一点:
让事情变得非常简单
不要重复造轮子
尽可能使用经过验证的可靠技术
技术栈
Instagram 早期的基础设施运行在 AWS 上,使用 EC2 和 Ubuntu Linux
EC2 是 Amazon 的云服务,它允许开发人员租用虚拟机
前端 APP
Instagram 最初在 2010 年作为 iOS 应用程序推出。由于 Swift 在 2014 年才发布,那 Instagram 应该是使用 Objective-C 和 UIKit 等其他语言的组合来编写的
负载均衡
Instagram 使用了 Amazon 的 Elastic 负载均衡器(Load Balancer)。他们有 3 个 Nginx 实例,Nginx 之间会进行健康检查以此保证服务高可用
当用户请求到来时,每个请求会先经过负载均衡器,然后才被转发到后端实际服务器
后端服务
Instagram 的应用程序服务器使用了 Django 框架,它是由 Python 编写的,而 Gunicorn 是它们的 WSGI 服务器
WSGI (Web Server Gateway Interface)全称 web 服务器网关接口,它会将请求从 web 服务器转发到 web 应用程序
在批量管理和自动运维方面,Instagram 通过 Fabric 同时在多个实例上面并行运行命令,做到几秒钟内部署代码
Fabric 是 Python 的一个模块,基于 SSH 提供了丰富的交互接口,可以用来在本地或远程机器上自动化的执行 Shel l命令,非常适合用来做应用的远程部署及系统维护
这些实例在超过25台 Amazon High-CPU Extra-Large 机器上运行。由于服务器本身是无状态的,如果需要处理更多请求时,便可以添加更多的机器
一般数据存储
Instagram 使用了 PostgreSQL 来存储数据,应用程序服务器将从 PostgreSQL 中提取数据,PostgreSQL 存储了 Instagram 的大部分数据,例如用户和照片元数据
PostgreSQL 和 Django 之间的连接通过 pgbouncer
pgbouncer 是一个 PostgreSQL 连接池
任何目标应用程序都可以像连接 PostgreSQL 服务器一样连接到 pgbouncer,并且 pgbouncer 将创建到实际服务器的连接,或者重用其现有的连接
Instagram 对用户的数据进行了分片,即使用代码将几千个“逻辑”碎片映射到几个物理碎片,因为收到的数据量很大(每秒超过 25 张照片和 90 个赞)
但是在将数据写入这组服务器之前,Instagram 必须解决如何为数据库中的每条数据分配ID(唯一标识符)的问题
下面则是 Instagram 中每条数据 ID 包含的内容:
41 位表示时间(以毫秒为单位)
13 位表示逻辑分片 ID
10 位表示自动递增序列,模数 1024。这意味着我们可以在每毫秒内为每个分片生成 1024 个id
Instagram 的数据分片和 ID 具体是怎么解决的小伙伴们可以看这篇文章:
https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c
照片数据存储
对于用户的照片,Instagram 使用 Amazon S3 来存储,并且使用 Amazon CloudFront 把照片快速提供给用户
缓存
Instagram 使用 Redis 将大约 3 亿张照片映射到创建它们的用户 ID 进行存储,所有 Redis 都存储在内存中以减少延迟,并在多台机器上进行分片。
通过一些巧妙的散列,Instagram 能够在不到 5 GB 的内存中存储 3 亿个键映射
对于常规缓存,Instagram 使用了 Memcached。他们当时有 6 个 Memcached 实例。Memcached 相对容易叠加在 Django 上
PostgreSQL 和 Redis 都使用了主从架构,并使用 Amazon EBS(弹性块存储)快照对系统进行频繁备份
推送通知和异步任务
Instagram 使用 pyapns 来实现,Pyapns 是一个开源的、通用的苹果推送通知服务(APNS)提供商
在后端,任务被推送到 Gearman,这是一个任务队列,将工作分配给更适合的机器。Instagram 有 大约 200 名 Python 工作者使用 Gearman 任务队列
Gearman 常用于多个异步任务,例如向用户的所有关注者推送活动(发布的新照片)
监控
Instagram 使用开源 Django 应用程序 Sentry 来实时监控 Python 错误
Munin 用于绘制系统范围的指标并发出异常警报。Instagram 有一堆自定义的 Munin 插件来跟踪应用程序级别的指标,例如每秒发布的照片
Pingdom 用于外部服务监控,PagerDuty 用于处理事件和通知