转载

漫谈从零访问量到每秒千万访问量的架构设计

漫谈从零访问量到每秒千万访问量的架构设计

漫谈从零访问量到每秒千万访问量的架构设计

在进行一切讨论前,有必要先看几个压测工程师经常提到的术语。

漫谈从零访问量到每秒千万访问量的架构设计

RPS

漫谈从零访问量到每秒千万访问量的架构设计

RPS(Requests Per Second)指系统在单位时间内 (每秒)处理请求的数量 。比如在 100 秒内给一个系统发起 1000 个请求,而这些请求在这 100 秒时间内全部返回了,那么可以认为系统经受住了 1000/100 = 10 RPS 的流量。为了严谨性需要说明一下:这里用 100 秒而不是 1 秒,是考虑到减小时间边界引起的误差(考虑第 1 秒钟和第 100 秒钟的请求以及响应,他们一定概率是不完整的)。

漫谈从零访问量到每秒千万访问量的架构设计

并发度

漫谈从零访问量到每秒千万访问量的架构设计

指在同一个时间点发起的请求数量,比如 12306 统一在下午两点钟放票,100 个人在下午两点钟同时向 12306 发起请求,此时可以认为并发度为 100。

漫谈从零访问量到每秒千万访问量的架构设计

QPS

漫谈从零访问量到每秒千万访问量的架构设计

QPS(Query Per Second) 是指在一定并发度下,服务器每秒可以处理的最大请求数。QPS 与 RPS 的定义类似,但前者是后者的一个极限值,且前者受到并发度的约束。

为什么说 QPS 要受到并发度的约束呢?可以想象这样两个场景:① 一个系统在 1 个并发的情况下的 QPS 为 100,这就意味着每个请求的响应时间为 1/100 = 0.01 秒。

② 一个系统在 10 个并发的情况下 QPS 为 100, 对于每个并发来说,每个请求的响应时间变成了 1/(100/10) = 0.1 秒。从上面可以看出,相同的 QPS 下,并发度不同,响应时间不同,用户的体验自然也不同。

漫谈从零访问量到每秒千万访问量的架构设计

服务器平均请求处理时间 与 用户平均等待时间

漫谈从零访问量到每秒千万访问量的架构设计

服务器平均请求处理时间 = 1/QPS(秒)。如果一个系统的 QPS 为 1000,无论请求是由 1 个并发发起的还是 100 个并发发起的, 均意味着服务器处理一个请求的平均时间为 1/1000 = 0.001 秒。但是在并发度不同时,相同的 QPS 数据用户感受到的响应时间是不同的,这就有了:用户平均等待时间 = 1/(QPS/并发度) = 并发度/QPS(秒)。

漫谈从零访问量到每秒千万访问量的架构设计

百RPS——升级机器配置

漫谈从零访问量到每秒千万访问量的架构设计

对于一百 RPS 以内的流量,目测只需要考虑升级机器的配置即可。

目前 1c2g 的机器配置同时支撑了 Web 应用以及 Mysql 应用以及一些其他用于监控的应用。流量增加后,可以先考虑升级机器的配置,比如升配到 8c16g 的机器。这种情况下,应用架构、部署方案等均不需要做大的修改。在使用了云主机的情况下,只需要①关机、②升配、③重启三步即可。

漫谈从零访问量到每秒千万访问量的架构设计

千RPS——各组件拆分并优化

漫谈从零访问量到每秒千万访问量的架构设计

考虑到单台服务器的配置并不能无限的升级(升级 CPU、内存后可能其他指标也会出现瓶颈,比如磁盘IO),对于一千 RPS 以内的流量,可以考虑拆分各个组件并优化部署到专用的服务器。

具体的:①修改原来的部署方案,比如把 Web 应用与 Mysql 数据库分别部署到不同的机器。② 对各个组件的性能进行重新评估,查找性能瓶颈的点以后对应用进行改造。比如 Mysql 数据查询遇到性能瓶颈,一方面考虑升级 Mysql 专用服务器的配置;另一方面对应用层进行改造,引入 Redis 做缓存,减少对 Mysql 的查询次数,从而降低它的压力。

漫谈从零访问量到每秒千万访问量的架构设计

万RPS——水平扩展

漫谈从零访问量到每秒千万访问量的架构设计

在万RPS的时候,假如单个 Web 的吞度量被压榨到了极限,此时可以考虑水平扩展 Web 应用了,必要情况下考虑水平扩展 Database。

对 Web 应用来说,引入 nginx 做一层反向代理,把流量均发到后面的服务器去从而减少对每台服务器的压力。对于数据库来说,可以考虑进行主备设计,① Web 层对主库进行写操作,② 多个从库同时到主库同步数据,③ Web 层对主库和从库进行读操作。

漫谈从零访问量到每秒千万访问量的架构设计

十万、百万、千万RPS——终极拆分及扩展

漫谈从零访问量到每秒千万访问量的架构设计

在 RPS 到达了十万以上的时候,简单的水平扩展已经没有办法满足需求了,这个时候很多地方都会相继出现瓶颈。

① 反向代理的地方出现瓶颈。简单来说,由于用户实在太多了,一个入口已经无法满足需求,这个时候需要想办法对反向代理进行水平扩展。比如在不同地域的 DNS 服务器配置不同的 nginx 实例的地址,从而把不同地域用户的请求分发到不同的 nginx 实例上。

② 数据库遇到瓶颈。单个数据库已经无法响应所有的请求(因为数据量大,主从设计也不能满足需求了);这个时候需要对数据库进行水平分割(或垂直分割),把不同的数据表拆分到不同的数据库(拆库),或者把同一个数据表里的数据拆分到不同数据库的不同表(拆表),从而增加数据库的吞吐量。

③ 在拆库时,一般会根据功能模块把数据表拆分到不同的数据库,从而实现每类数据库对应不同的功能模块;这个时候需要考虑分布式事务的设计。比如一个系统中存在账户模块和商品模块,账户模块依赖的数据库中主要包含的是用户相关的数据表,商品模块依赖的数据库中主要包含的是商品相关的数据表。当某个用户购物时,其账户中的财富值与其购物单之间存在数据一致性的问题,必须限定 a) 只有在下单成功的情况下才允许扣除用户账户中的财富值,b) 否则下单失败同时账户的财富值也不会扣除。

上面的讨论给出的是一种抽离了业务本身的粗线条架构方案,对应到实际的业务时需要根据具体的领域知识对架构进行细化,否则没有工程实践意义的。

漫谈从零访问量到每秒千万访问量的架构设计

小结

漫谈从零访问量到每秒千万访问量的架构设计

本文构思了一种架构设计,用于解决超高并发 Web 应用的性能瓶颈。首先解释了 RPS、并发度、QPS、服务器平均请求处理时间、用户平均等待时间等几个专业术语,接着假设在网页流量增加到不同的量级时分别考虑采取的应对措施,最后给出了一种终极解决方案以应对千万 RPS 的场景。

为什么很多SpringBoot开发者放弃了Tomcat,选择了Undertow

谷歌开源内部代码评审规范

UML (统一建模语言) 各种图总结

真实项目案例实战—【状态设计模式】使用场景

漫谈从零访问量到每秒千万访问量的架构设计

欢迎分享转发,有帮助的话点个“在看”

点我查看原文

原文  http://mp.weixin.qq.com/s?__biz=MzU2NDc4MjE2Ng==&mid=2247484542&idx=1&sn=b9ab61170044c570f6518679c230f66d
正文到此结束
Loading...