内容简介:在没有正式在中国市场登陆的情况下,Instagram 已经突破10亿用户了。这个产品的用户活跃度非常之高。它从工程的角度来说,它跟朋友圈和微博有两个不同的需求。1. 它的用户几乎均匀的分布在全世界,而中国产品的用户绝大多数在中国。2. 它是公开社交,这点更像微博,而朋友圈是熟人社交。
在没有正式在中国市场登陆的情况下,Instagram 已经突破10亿用户了。这个产品的用户活跃度非常之高。它从工程的角度来说,它跟朋友圈和微博有两个不同的需求。1. 它的用户几乎均匀的分布在全世界,而中国产品的用户绝大多数在中国。2. 它是公开社交,这点更像微博,而朋友圈是熟人社交。
Instagram 截止2018年6月的规模
- 10亿月活跃用户,80%以上用户不在美国。女性用户大约是男性的1.5倍
- 每天100亿次以上的点赞
- 每天10亿次以上的上传图片或视频
- 最大账号,1.1亿以上的粉丝数量。比如下面两位:
可以看出,Instagram 是一个极其庞大的网站
下图是Instagram 的全球数据中心分布。绿色的是使用 Facebook 的数据中心,红色的是使用 AWS,黄色的计划建设的。
为了测试整个网站的稳定性,Facebook 也会经常做 Chaos engineering 测试:在 production 环境下关闭一个 data centre,看网站是否能正常运行。
AWS 曾经在 2017年3月出现过一次较长时间的 outage。像 instagram 这个用户规模的网站如果完全依赖于 AWS,那么可能出现灾难性的后果,那将完全指望 Amazon 尽快修好自己的 server。
上面这个图是大体上的架构。
- Django 做 web server,使用 Python
- Casaandra 是 NoSQL 数据库
- PostgreSQL 是关系型数据库
- memcache 做缓存
- RabbitMQ是消息队列
- Celery 是后台任务系统
在 Instagram 大体有两类 services。一类是 storage 存储,一类是 computing 计算。
Storage 存储
PostgreSQL 存储更多需要做 join 操作的数据,比如用户之间的 follow 关系。这里使用 master 和 replica 的结构,实现 eventually consistency。replica 分布在不同的 data centre。Django 将数据写入 master,而从 replica 读取,这样读写分离。实际应用中发现,master 到 replica 这个延迟对业务没什么影响。
Cassandra 存储用户发的 post,用户活动记录等等。Cassandra 自己是一个没有 master 的 NoSQL 数据库,各 replica 之间实现 eventually consistency 。Cassandra 的 consistency 是通过 Quorum 机制实现的,所以根据业务的不同,通过调节 quorum 数量可以配置不同程度的 consistency。
Datastax 这篇文章 介绍了Cassandra 和 quorum 机制
Computing 计算
不同于存储,每个 region 在计算方面是相对独立的。在每个 region ,Instagram 都部署了 Django,Celery 和 RabbitMQ。Load balancer 会把 request 发给本地的 Django,backend job 和 queue message 也是在当地 region 运行。
Memcache
因为 cache 的目标就是为了提速,也就是说从 CAP 理论来讲,追求 low latancy,所以会牺牲 consistency。 进而也就是说,如果一个美国用户发了一条 post ,欧洲用户晚那么几分钟收到也没什么关系。
现在假设一个场景。一个用户发了一条 post 。web server (这里指 Django)将这条 post 被写入了 PostgreSQL,也写入了当地 data centre 的 memcache 里面。此时另一个用户访问这条 post 时:
- web server 总是先尝试从 memcache 读取数据。如果读者用户也在当地,那么可以直接从 memcache 读到 post
- 而如果读者在其他地区,此时因为延迟,读者不一定能及时读到 post
那如何将这条 post 复制到其他地区的 memcache呢?
- 发布者地区的 data centre 会通过 PostgreSQL 复制机制,将数据复制到其他地区,也就是图中右边部分的 DC2
- DC2 的 PostgreSQL 会告诉当地的 memcache 说,相关的数据过期了(比如说这个发布者的所有最近 post 这个数据已过期),应把它从 memcache 里清除。DC2 的 web server 之后发现 memcache 里没有需要的数据,会从 PostgreSQL 读取,然后更新 memcache
而当数据从 memcache 被清除的那一刻,如果流量很大,那么所有的 web server 瞬间全部转向 PostgreSQL 询问。这时 database 的压力非常大, 极有可能影响其他业务。
这个在英文里叫 thundering herd problem,中文常常叫缓存的雪崩效应。
解决的办法是使用 memcache lease 机制。当第一台 web server 找 memcache 要数据时,memcache 说“我没有数据,你去 database 拿最新数据来更新我吧”,而再之后的 web server 再来问, memcache 说“我没有数据,但是有人去拿数据了。你要么等等,要么用我这里过期的数据吧”
Scale UP 纵向扩展优化
Instagram 会尝试提高每台服务器的效率,而不是一味的增加服务器数量。比如使用高效的代码,更加底层的代码,从而提高CPU使用率。
为了帮助 scale up,Instagram 对 CPU 使用率做了监测、分析和优化。
- 监测:在服务器上将 CPU 使用率信息发送给专门的平台统计。当使用率出现异常变化时,会触发警报。有时候这些变化是因为发布了新功能造成的。这也有助于 Instagram 分析哪些功能还有提高空间。
- 分析:在 Django 中使用了 Python cProfile 库,它可以用来分析函数调用栈的各层中所使用的时间(这个过程叫做 profiling),生成的结果可以被其他 工具 绘制成图(如上图)。但要指出的是,profiling 对性能是有挺大影响的。所以不要将 profiling 代码一直运行,而是偶尔运行。
- 优化:Instagram 在服务器端,针对逻辑使用了一些优化技巧。比如用户请求一张图片的 url 时,根据用户的位置,服务器直接返回离用户最近的 cdn url 地址。再比如将一些经常被调用的函数使用 Cython 或者 C/C++来写,减少实际调用的 CPU 指令
纵向扩展的另一个方面叫做 less server (减少服务器数量)。一台服务器上要运行很多 process。这些process 之间,在内存中,有时是可以共享同一段代码,有时使用自己的独立内存空间。如果让一台服务器上的 process 尽量多的共享代码,比如让同类的 process 运行在同一台服务器上,那么在 cluster 中就可以减少服务器数量。
网络延迟也是可以优化的一方面。
比如 Instagram app 的首页分为几个部分。为了提高 app 响应速度,客户端 app 是通过异步的方式,从不同的 service 请求不同的数据,再展示在 app 上,而并不是从同一 service 同步获取。
附:开发流程
Instagram,如 以往文章中提到的 Google 开发流程一样 ,也是使用 Trunk based development。新功能直接在 master branch 开发,使用 CI 控制代码质量。这使得各个功能的开发团队都能使用最新代码。同时,Instagram 会持续监测代码的性能。
代码上线的过程是:工程师开发功能 -> 测试团队测试,反馈 -> 内部员工 alpha 测试 -> Canary deployemnt (灰度发布/金丝雀发布)-> 100% 上线。上线的过程中会逐步进行 load test 负载测试。上线过程使用了自动化的 Continuous delivery (持续支付)流程,所以每天能 deploy 40-60 次。deploy 一次需要大概10分钟,就能 deploy 到 20k+ 服务器上。
参考资料: Scaling Instagram
微信公众号:网站架构札记
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【架构入门 - 可扩展篇】
- 域控管理员帐户架构扩展
- 架构的终极目标——可扩展
- 微服务架构:自动扩展简介
- 系统架构系列(五):技术架构之高可扩展系统设计与实现
- 构建可扩展的架构 - Koinex Crunch
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。