当你向用户辛辛苦苦的推销一个产品,用户已经决定登陆网站去下单的时候,却因为等了五秒,页面还没加载出来,而说了一声:下次吧,你的心可能就是凉凉的。
这可能就是为什么人们想要设计一个高性能的网站的原因了。
高性能和高可用其实是非常相关的话题,性能差到极点就是一种不可用,把可用做的好一点也能提高性能。但今天我们主要谈一谈如何设计一个高性能的网站,或曰网络服务。
性能设计的前人经验
如果你正在忍受着性能的困扰,有急迫的愿望想要提高性能,那么首先恭喜你,你进步了,你的用户变多了。
但针对不同的场景,满足性能提升这个需求的做法是不一样的。我们最好具体问题,具体分析。
如果你原来是单台服务器部署的:应用服务 + 数据库 + 文件服务都在一台机器上,那么针对不同的情况,你可能会想到不同的办法[1]:
如果你的瓶颈出现在应用服务的接受能力上:
- 把应用服务抽离出来,用一台 CPU 更好的机器来运行相关服务,因为应用服务需要大量逻辑计算;
- 也可以把应用服务部署在多台机器上,用负载均衡(选择适合的分发算法),把请求分发到多台机器上,每台机器只负责自己的流量,避免处理不过来。
如果瓶颈出现在数据的访问上:
- 那么可以看看数据的特点,如果这些数据中有热点数据,那么可以把其中状态比较稳定,不经常改变的数据缓存起来;缓存可以选择本地缓存,也可以选择专门的缓存服务器(如果你觉得一台的内存空间不够的话,可以建立一个集群做缓存,这个我们在“如何设计高可用网站”时会讨论)。
- 如果数据的状态需要经常查询,但是不经常改变,可以通过建立索引,提高读取性能。
- 进一步,还可以实现主从两个数据库,让主数据库(Master)只负责写,实现数据库的读写分离。
如果你的瓶颈出现在一些静态文件的下载上:
- 静态文件发生改变的频率通常不太高,可以利用CDN,反向代理等机制加速用户获得文件等过程
最后,前端也可以做一些优化,比如:
把 js 文件放在 body 的后半部分进行加载,适当的把 css、js 文件聚合到一起,不要太少,太少的话一个文件过大,下载很慢,而且没法在浏览器中多线程的下载;但也不要太多,太多的话会把很多时间花费在建立 http 链接上。
为了看的更清楚一点,我画一张图给你:
初具规模的架构最终,上面说的各种瓶颈,随着你的发展,你真的都遇到了,那么再次恭喜你。
但如果你已经发展到这个地步,数据量很大,想要继续提高性能,那么我们可以继续拆分数据,拆分业务,具体来说就是:
如果你的瓶颈出现在了数据的读写上:
- 可以把一张表拆分成多个(分表),水平切分,或者垂直切分。2. 也可以把不同业务的数据分拆到不同的数据库,这样应用服务对于原先单一主数据库(Master)的写操作可以分散的不同的数据库中。(这样的分库分表我们接下来会接着讨论)
- 将一些数据存储在 NoSQL 的数据库上,这些 NoSQL 的通常提供一个特性:保障数据的读取时间恒定,同时也适合多节点的分布式存储。
如果你的瓶颈出现在应用服务上:
- 可以把其中一部分重要服务拆出来,单独部署,用更好的资源去运维。比如首页、订单、支付这样的服务。
- 在不同服务之间相互调度的时候,可以引入异步机制,实现一个阻塞队列,来用生产者消费者的模式处理一部分事务。
我们修改一下上面的图,看看我们的架构已经是什么样子了:
更复杂的网络服务系统我们图中每个服务只画了了一两台机器,但其实,在这样的架构下,他们有能力拓展到更多台。
当然,除了上面这些架构上的问题,也需要工程师们写代码的时候,考虑性能,引入多线程。
五大方向
上面的零零碎碎都是一些别人实践出来的经验,但其实还有更多方法,比如不同地区的DNS指向不同的服务器,方法都可以自己想,而不一定是 google 别人的经验。但在自己思考的时候,有 5 个方向可以作为思考的起点:
- 改善硬件
- 使用缓存
- 引入(分布式)集群
- 引入异步
- 优化代码
这五个方向,依据的也是前人的经验。但排除掉具体的细节,可能更有利于你自己发挥。
后面的文章中我们就讲一讲这五大方向上的一些细节。
-
参考 《大型网站技术架构》 ↩
网友评论