码迷,mamicode.com
首页 > Web开发 > 详细

【读书笔记】第四章 瞬时响应:网站的高性能架构

时间:2015-07-12 12:58:03      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:

第四章 瞬时响应:网站的高性能架构

4.1 网站性能测试

4.1.1 不同视角下的网站性能

1.用户角度:网站响应速度快还是慢
2.开发人员:关注系统本身及其子系统的性能,响应时间,吞吐量,并发能力,稳定性等指标。
3.运维人员:关注基础设施和资源利用率,比如贷款能力,服务器配置,数据中心网络架构等。

4.1.2 性能测试指标

1.响应时间 下表是一些常用的系统操作所需要的响应时间

技术分享
2.并发数:系统能够同时处理的请求数目
3.吞吐量:单位时间内,系统处理的请求数量(注意与并发数区分)。TPS(每秒事务数),QPS(每秒查询数),HPS(每秒HTTP请求数),都可以作为衡量指标。

把吞吐量,并发数和响应时间的关系可以理解为高速公路的同行状况:吞吐量表示每天通过收费站的车辆数目,并发量表示高速公路上正在行驶的车辆数目,响应时间是车速。

4.性能计数器:描述的是服务器或操作系统性能的数据指标,包括SystemLoad,对象与线程数,内存和CPU使用情况,磁盘与网络I/O等指标。

SystemLoad,即系统负载,指 当前正在被CPU执行和等待被CPU执行的进程数目总和,是反映系统忙闲程度的重要指标。Linux系统中的Load Average。关于Load Average的说明请参考Evernote中的笔记。

4.2 Web前端性能优化

4.2.1 浏览器访问优化

1.减少HTTP请求
合并CSS,合并JS,合并图片

2.使用浏览器缓存
对于静态资源文件来说,这些文件更新频率低,无需每次都从服务器获取,可以将这些文件缓存在浏览器中。通过设置HTTP请求头中Cache-Control,Expires等属性可以设定浏览器缓存。
当静态文件需要更新时,采用增量更新方法,比如需要更新10个图标文件,不宜把10个图标一次性更新,而是应当一个文件一个文件的更新,并有一定时间间隔,以避免用户浏览器突然大量缓存失效,请求服务器,造成服务器负载骤增,网络堵塞等问题。

3.启用压缩
在服务器端对文件压缩,浏览器端解压缩,从而减少传输数据量。HTML,CSS,JS文件启用GZIP压缩可以达到较好的效果,需要考虑压缩对服务器端和解压浏览器端的压力。

4.CSS文件放在页面最上面,js放在页面最下面
浏览器会在下载完全部css之后才会对整个页面进行渲染,因此最好的办法就是将CSS放在页面最上面。JS则相反,浏览器在加载js后立即执行,有可能会阻塞整个页面,造成页面显示缓慢。但如果页面解析时就需要用到js,那就不能放到最底部。

5.减少Cookie传输
对于静态资源来说,在请求的时候一般是不需要Cookie的,所以可以考虑将静态资源使用独立域名访问,避免请求静态资源的时候发送Cookie,减少Cookie传输次数。

4.2.2 CDN加速

CDN(Content Delivery Network)内容分发网络,本质是一个缓存,可以让用户访问离他自己最近的资源,以提高速度,即所谓网络访问第一跳。
CDN缓存的一般都是静态资源。

4.2.3 反向代理

反向代理的几个作用:1)静态资源缓存 2)安全控制 3)负载均衡
在提高网站性能方面,反向代理可以通过配置缓存加速Web请求。当用户第一次访问静态资源的时候,静态内容就被缓存在反向代理服务器上,当用户再次访问的时候,就可以直接从反向代理服务器返回。(某些动态内容也可以放到反向代理服务器上缓存)

4.3 应用服务器性能优化

应用服务器:处理网站业务的服务器,业务代码都在这里,是网站开发最复杂,变化最多的地方,优化手段主要有:缓存,集群,异步等。

4.3.1 分布式缓存

网站性能优化第一定律:优先考虑使用缓存优化性能

1.缓存的基本原理

缓存:将数据存储在访问速度相对较高的存储介质中,以供系统处理。优点:
1)缓存访问速度快,可以减少数据访问时间。
2)对于需要经过计算得到的数据,放到缓存中可以减少不必要的重复键算,从而减少计算时间。

缓存的本质是一个内存Hash表,Hash表读写的时间复杂度为O(1)。

网站数据访问的“二八原则”:即80%的访问请求会落在20%的数据上。因此将这频繁使用的20%的数据缓存起来,可以很好的改善系统性能。

2.合理使用缓存

频繁修改的数据:数据改动频繁,会出现数据写入缓存之后,应用还没来得及用数据就过期了的情形。 一般来说,数据的读写比在2:1以上,即写入一次数据,在数据更新之前至少会被读取两次,缓存才有意义。
没有热点的访问:缓存使用内存存储,内存资源有限,因此如果对于访问的数据不满足二八定律,即大部分访问并没有落到小部分数据上,那么缓存就没有太大意义。
数据不一致与脏读:缓存到了过期时间之后,需要重新加载数据,因此要容忍一段时间的数据不一致。另外还有一种策略是数据更新时立即更新缓存,不过会增加系统开销,还会存在事务一致性的问题。
缓存可用性


“缓存雪崩”:当缓存服务崩溃时,所有的数据请求会直接落到数据库,会导致数据库无法承受突然猛增的巨大压力而宕机,进而导致整个网站不可用。

在实践中,有通过缓存热备等手段提高缓存可用性:当一台缓存服务器宕机的时候将缓存访问切换到热备服务器上,但这有悖于缓存设计的初衷:缓存根本就不应该被当做一个可靠的数据源来使用!
通过分布式缓存服务器集群,可以一定程度改善缓存的可用性。
缓存预热:缓存中存放的是热点数据,一般都是通过LRU算法不断筛选得到的,这个过程比较耗时。所以,可以在缓存系统启动的时候把热点数据加载好。
缓存穿透:如果因为不恰当的业务、或者恶意攻击持续高并发的请求某个不存在的数据,由于缓存中没有该数据,所有的请求都会落到数据库上,会对数据造成很大压力,甚至崩溃。简单的对策就是:将不存在的数据也缓存起来(其value值为null)。

3.分布式缓存架构

分布式缓存:将缓存部署在多个服务器组成的集群中,以集群方式提供缓存服务。
两种架构方式:
1. 以Jboss Cache为代表的需要更新同步的分布式缓存。
2. 以Memcached为代表的不相互通信的分布式缓存。

4.Memcached

Memcached采用一种集中式的缓存集群管理,也称作互不通信的分布式架构方式。 缓存与应用分离部署,缓存系统在部署在一组专门的服务器上,应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据。集群规模容易扩容,伸缩性好!
技术分享

简单的通信协议
远程通信设计需要考虑两方面的要素:1.通信协议2.通信序列化协议。
memcached采用TCP(也支持UDP)作为通信协议,采用一套简单的基于文本的自定义协议作为序列化协议。
丰富的客户端程序
支持多种语言。
高性能的网络通信
服务端通信模块基于Libevent,Libevent的设计和实现有许多值得改进的地方,但是它稳定的长连接却是memcached所需要的。
高效的内存管理
内存管理中一个比较头痛的问题就是内存碎片管理。操作系统,虚拟机垃圾回收在这方面想了很多办法:压缩,复制等。
Memcached采用了一个非常简单的办法:固定空间分配。
将内存空间氛围一组slab,每个slab里面又包含一组chunk,同一个slab中的每个chunk的大小是固定的,拥有相同大小chunk的slab被组织在一起,叫做slab_class。
存储数据的时候根据数据的所占空间大小Size,寻找一个大于Size的最小的chunk存放数据。
这种方式避免了内存碎片管理的问题,内存的分配和释放都是以chunk为单位的。

Memcached也是用LRU算法释放最近最久未被访问的数据的空间,释放的chunk被标记为未使用,等待下一个大小合适的数据的写入。

当然这种方式也会造成空间的浪费,chunk的大小等信息是可以通过配置设置的,如果启动的时候设置的大小不合适,就会导致严重的空间浪费。

互不通信的服务器集群架构

正式集群内服务器不相互通信使得集群可以几乎无限制的线性伸缩!

4.3.2 异步操作

使用消息队列具有很好的削峰作用,即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。
任何可以晚点做的事情都应该晚点再做

4.3.3 使用集群

4.3.4 代码优化

  1. 多线程
  2. 资源复用:对于创建对象开销很大的对象进行复用。

    从编程角度,复用一般两种方式:1.单例模式 2.对象池
  3. 使用合适的数据结构

  4. 垃圾回收

    JVM中的垃圾回收:
    JVM中将内存分为堆和栈。栈用于存储线程上下文信息,如方法参数,局部变量等。堆是存储对象的内存空间,对象的创建和释放,垃圾回收就在这里进行。
    JVM分代回收机制:
    JVM将堆空间氛围Young和Old两个Generation,Young代又分为一个Eden区域和两个Suvivor区域。新创建的对象总是在Eden区域中,当Eden区域空间已满,就会触发一次Young GC,此时会将仍在被使用的对象复制到一个Suvivor区域中,然后将Eden区域和另一个Suvivor区域回收掉。当Eden区域再次用完的时候,会再触发一次YoungGC,将Eden区域和之前一个Suvivor区域中的仍被使用的对象都复制到另一个Suvivor区域中,然后将Eden和第一个Suvivor区域清空。经过多次YoungGC之后,某些对象会在两个Suvivor区域中复制多次,如果超过某个阀值对象还没有被释放,则对象会被复制到Old Generation中。如果OldGeneration的空间也已经用完了,则会触发一次FullGC,即所谓的全量回收。

4.4 存储性能优化

4.4.1 机械硬盘VS.固态硬盘

固态硬盘没有机械装置,数据存储在可持久记忆的硅晶体上,因此可以像内存一样快速随机访问。而且SSD具有更小的功耗和更少的磁盘振动与噪声。

4.4.2 B+树 VS. LSM树

RAID VS. HDFS

RAID(廉价磁盘冗余阵列)技术主要是为了改善磁盘的访问延迟,增强磁盘的可用性和容错能力。

【读书笔记】第四章 瞬时响应:网站的高性能架构

标签:

原文地址:http://my.oschina.net/jasonultimate/blog/477514

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!