/**
*@简介:本文介绍web服务端的高性能技术,或者说网站性能优化技术
*@创建时间:2014/7/14
*/
一、 什么是网站性能
我们知道,web系统是一个由一个服务端和众多客户端构成的分布式应用系统。该系统的主要功能是接收用户的请求后返回响应结果给用户。那么,从用户使用的角度来看,网站的性能指的是用户操作的响应时间:
用户响应时间:用户通过客户发起一个操作,到看到客户端返回的响应结果之间的时间间隔。
网站服务端开发工程师,更多关注的是服务端应用系统(指承载业务逻辑的核心系统,比如Apache+PHP)和相关子系统(比如数据库、缓存系统等)的性能。这些系统的性能指标主要有:
系统响应时间:对系统的操作,从发出操作请求道返回操作结果之间的时间间隔。
系统并发数:系统同时能够处理的请求的数目。
系统吞吐量:系统单位时间内处理的请求数。
系统性能计数器:描述系统性能的一些数据指标,比如system load、对象与线程数、cpu、内存、磁盘IO、网络IO等指标。
顺便提一下,对于运维人员,所关注的网站性能又有所不同,他们关注的性能是服务端系统基础设施(服务器、网络)本身的性能以及这些资源的利用率。
对于服务端开发人员,之所以要关注上面提到的服务端系统的4个性能指标,是为了能够使服务端的设计能够满足整个web系统能够提供足够短的用户响应时间。这是业务决定技术设计的一个体现。离开了用户视角的性能,优化服务端做的性能就成了无的放矢的蠢事。
因此,下文关注的网站性能指的是服务端的4个系统性能。
二、 如何测试(测量)网站性能
我们可以通过模拟真实请求场景,从小规模的请求并发量开始,不断增加并发量,来测试不同并发量下系统的响应时间、吞吐量、性能计数器等性能指标。
需要知道系统在以下3各阶段的性能指标:
性能测试:正常运行区间的性能
负载测试:系统最大负载能力(找出最大负载点)
压力测试:系统最大承压能力(找出崩溃点)
另外,如果加上稳定性这个指标,还测试系统在特定条件下、特定业务压力下在某段适宜长度时间段内的运行稳定性。
三、 性能优化步骤
1. 利用日志找出哪个环节的响应时间造成系统瓶颈。
2. 利用监控数据,分析导致瓶颈的原因,比如找出是cpu、内存、磁盘、网络问题还是架构设计不合理,或者确实是资源不足等。
3. 使用下一节的高性能技术对服务端性能进行优化。(性能优化也应考虑web前端的优化技术,不过这不在本文的讨论范围内)
四、 服务端高性能技术
以下是本文的重点了,我们将介绍目前互联网业界常用的能够有效提高web服务端性能的技术,通过这些技术,我们的服务端应用系统就能够跻身高性能的行列。
正如上文提到过的,技术是服务于业务的,也就是说,本节所列的高性能技术主要要解决的问题是:如何在高并发访问的情况下,缩短用户视角的响应时间。同时,需要注意的是,这些技术不可避免的会导致服务端架构的复杂化以及系统内部的网络延迟,这样可能会导致性能优化后,高并发访问的响应时间缩短了,但低并发访问的时间却延长了,这个问题需要我们心里有数。
CDN
能够在网运营商机房部署的CDN服务器缓存服务端的内容(要有更新或同步机制),这样,客户端能够在网络的第一跳就能访问到所需要的内容。
另外,CDN技术还能够将客户端的访问流量导到离该客户端最近的内容提供商的机房,这样同样可以缩短响应时间。
反向代理
反向代理是一台服务器(应该也可能集群),它在部署在web服务器前,代理网站web服务端的http请求。
在这里通过缓存数据和使用负载均衡技术(均衡地转发http请求到web服务器集群)缩短响应时间。
分布式缓存
缓存指将数据存储在访问速度相对较高的存储介质中。在web后端系统,这一般指把原先放在磁盘上的数据缓存到内存中。
缓存的目的是提高数据的访问速度和减少计算时间(把计算结果缓存起来无需重复计算)。
内存的缓存,本质上是一个内存hashtable。
缓存的使用同样要考虑业务,业务必须满足一些特点才适合使用缓存,这些特点包括:
1. 数据读写比高,写入缓存的数不能是频繁修改的,且被读取的次数应该很多次。
2. 有热点数据。
3. 能够忍受一定时间的数据不一致。(缓存的失效时间可能带来的数据不一致)
使用缓存的另外一些注意事项:
1. 缓存崩溃,不应该导致数据库承受不了压力而跟着崩溃,可以使用缓存集群来改善缓存的可用性。
2. 使用缓存预热使系统在缓存建立数据时的负载均衡。
3. 将不存在的数据也存起来防止缓存穿透(高并发请求缓存中不存在的数据,直接穿透缓存给数据库造成压力)
上面指出,单台缓存有可用性不高的缺陷,那么,现在一般使用分布式缓存,指的是部署在多个服务器组成的集群中的缓存。一下介绍一个典型的分布式缓存系统——Memcached。
Memcached由客户端和服务端组成,客户端部署在每台应用程序服务器(Apache+PHP)上,服务端部署在缓存集群的每一台服务器上。客户端和服务的直接的通信使用TCP协议(也支持UDP),通信协议的序列化使用一套基于文本的自定义协议,Memcached的服务端使用libevent这个事件触发的网络通信库,该库具有稳定的长连接特性。最最重要的是,Memcached使用:
一致性hash算法在集群中路由缓存数据的读写。
关于一致性hash是什么以及如何进行路由的,以后再介绍。敬请期待。
异步操作
异步操作的概念很简单,即将请求数据先存储在一个消息队列中,数据库作为消费者来取队列中的数据。这样,用户写数据库的操作就无需等待数据库,只有把要写的内容扔到队列中就可以直接返回了。等到数据库写完,再给用户一个异步的通知。
这种模式的基本前提是,消息队列服务器的速度要远快于数据库服务器。
需要注意的是,使用消息队列,可能需要适当修改业务流程进行配合。
使用集群
使用集群的目的,是将请求均衡地分发给应用服务器,避免单一服务器因为负载压力过大而导致高响应时延。
代码优化
多线程:系统会为每个用户请求创建一个线程进行处理,使用多线程可以在IO阻塞或多CPU系统中充分利用CPU资源。对于计算密集型任务,线程再多也没用,因为CPU资源就那些;而对于IO密集型任务,多线程有助于提供任务的并发度,因此可以提供系统吞吐量,改善系统性能,缩短高并发时的平均响应时间。
资源复用:对于无需重复的资源,使用单例;使用对象池复用对象实例,减少对象创建和资源消耗。比如数据库连接池、线程池。
数据结构:好的数据结构能够大大优化程序性能。
垃圾回收机制:该机制可能会对web服务端的性能产生很大影响,比如java垃圾回收机制中的全量回收会对系统的性能产生较大影响。
存储性能的优化
当前的一个事实是:机械磁盘的连续访问速度快而随机访问速度慢。而随机访问性能表现好的SSD(固态硬盘)目前还不太成熟,没有大规模投入使用。
当前的数据库或文件系统,通常会对数据进行排序后存储,以加快数据检索的速度,传统的关系型数据库一般用B+数,但B+数中的数据访问多涉及随机读写,磁盘性能差;另外,NoSQL产品采用了LSM数作为主要的数据结构,由于LSM更多地利用了内存,因此磁盘访问次数大幅度较少,加快了访问速度。
即,在当前的以机械磁盘做为主要存储介质的系统中,LSM具有更快的速度。
RAID
RAID可以理解单机上的多块磁盘构成的磁盘阵列。用来实现数据的并发读写和数据备份(增加可靠性)。该技术在传统的关系型数据库和文件系统的较常用。而在NoSQL以及分布式文件系统中,多用HDFS。
HDFS
HDFS是在存储集群的多台服务器上进行数据并发读写和备份。
备份指当应用程序写一个文件时,会被另外复制到另外两台机器上。
并发指通过MapReduce并发技术框架,可以启动多个计算子任务同时读取多个文件块。至于MapReduce是什么以及如何做到这么牛掰的功能,敬请期待后续文章。
总结一下我们的高性能技术:
技术本质 |
实例 |
缓存 |
CDN,反向代理,分布式缓存 |
异步 |
异步操作 |
负载均衡 |
集群 |
并发 |
多线程、RAID、HDFS |
复用 |
对象池 |
冗余 |
RAID、HDFS |
对于服务端研发工程师而言,和开发最相关的当属分布式缓存、代码优化(多线程、对象池、数据结构)、异步操作(消息队列)
五、 一些待学习的较深入的主题
分布式缓存
分布式缓存原理剖析(一致性hash原理)
分布式缓存实例的使用
Mapreduce并发技术框架原理
B+树和LSM树原理深入学习
消息队列技术概述
服务器集群构建原理和方法
PHP和JAVA高并发代码优化技术
……
(长路漫漫,敬请期待)
六、 参考资料
《大型网站技术架构-核心原理与案例分析》
===============================================================================
PS:我们是谁?我们是天边流云,有不成韵律的诗云:
《流云》
我们是天边漂泊的流云
常怀着游子的愁绪
我们曾贪慕青天的高远
也会迷恋新月的柔情
但终有一天我们寻到了故乡
哦,原来她正是这满目疮痍的大地
于是,我们等待风起时把我们连成一片
甘愿化成雨水,浇灌大地
更多…请见流云博客:http://thestrayclouds.blogspot.ae/(无法访问请发邮件到[email protected],我们将定期查看邮箱并告诉您访问方法)
===============================================================================